18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.javafx.font.freetype;
27
28 import com.sun.javafx.font.CompositeFontResource;
29 import com.sun.javafx.font.CompositeGlyphMapper;
30 import com.sun.javafx.font.FontResource;
31 import com.sun.javafx.font.FontStrike;
32 import com.sun.javafx.font.PGFont;
33 import com.sun.javafx.font.PrismFontFactory;
34 import com.sun.javafx.text.GlyphLayout;
35 import com.sun.javafx.text.TextRun;
36
37 class PangoGlyphLayout extends GlyphLayout {
38
39 private int getSlot(PGFont font, PangoGlyphString glyphString) {
40 CompositeFontResource fr = (CompositeFontResource)font.getFontResource();
41 long fallbackFont = glyphString.font;
42 long fallbackFd = OSPango.pango_font_describe(fallbackFont);
43 String fallbackFamily = OSPango.pango_font_description_get_family(fallbackFd);
44 int fallbackStyle = OSPango.pango_font_description_get_style(fallbackFd);
45 int fallbackWeight = OSPango.pango_font_description_get_weight(fallbackFd);
46 OSPango.pango_font_description_free(fallbackFd);
47 boolean bold = fallbackWeight == OSPango.PANGO_WEIGHT_BOLD;
48 boolean italic = fallbackStyle != OSPango.PANGO_STYLE_NORMAL;
49
50 PrismFontFactory prismFactory = PrismFontFactory.getFontFactory();
51 PGFont fallbackPGFont = prismFactory.createFont(fallbackFamily, bold,
52 italic, font.getSize());
53 String fallbackFullname = fallbackPGFont.getFullName();
54 String primaryFullname = fr.getSlotResource(0).getFullName();
55
56 int slot = 0;
57 if (!fallbackFullname.equalsIgnoreCase(primaryFullname)) {
58 slot = fr.getSlotForFont(fallbackFullname);
59 if (PrismFontFactory.debugFonts) {
60 System.err.println("\tFallback font= "+ fallbackFullname + " slot=" + (slot>>24));
61 }
62 }
63 return slot;
64 }
65
66 private boolean check(long checkValue, String message, long fontmap, long context, long desc, long attrList) {
67 if (checkValue != 0) return false;
68 if (message != null && PrismFontFactory.debugFonts) {
69 System.err.println(message);
70 }
71 /* pango_attr_list_unref() also frees the attributes it contains */
72 if (attrList != 0) OSPango.pango_attr_list_unref(attrList);
73 if (desc != 0) OSPango.pango_font_description_free(desc);
74 if (context != 0) OSPango.g_object_unref(context);
75 if (fontmap != 0) OSPango.g_object_unref(fontmap);
76 return true;
77 }
78
79 private long str = 0L;
80 public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
81
82 /* Create the pango font and attribute list */
83 FontResource fr = font.getFontResource();
84 boolean composite = fr instanceof CompositeFontResource;
85 if (composite) {
86 fr = ((CompositeFontResource)fr).getSlotResource(0);
87 }
88 long fontmap = OSPango.pango_ft2_font_map_new();
89 if (check(fontmap, "Failed allocating PangoFontMap.", 0, 0, 0, 0)) {
90 return;
91 }
92 long context = OSPango.pango_font_map_create_context(fontmap);
93 if (check(context, "Failed allocating PangoContext.", fontmap, 0, 0, 0)) {
94 return;
95 }
96 boolean rtl = (run.getLevel() & 1) != 0;
97 if (rtl) {
98 OSPango.pango_context_set_base_dir(context, OSPango.PANGO_DIRECTION_RTL);
99 }
100 float size = font.getSize();
101 int style = fr.isItalic() ? OSPango.PANGO_STYLE_ITALIC : OSPango.PANGO_STYLE_NORMAL;
102 int weight = fr.isBold() ? OSPango.PANGO_WEIGHT_BOLD : OSPango.PANGO_WEIGHT_NORMAL;
103 long desc = OSPango.pango_font_description_new();
104 if (check(desc, "Failed allocating FontDescription.", fontmap, context, 0, 0)) {
105 return;
106 }
107 OSPango.pango_font_description_set_family(desc, fr.getFamilyName());
108 OSPango.pango_font_description_set_absolute_size(desc, size * OSPango.PANGO_SCALE);
109 OSPango.pango_font_description_set_stretch(desc, OSPango.PANGO_STRETCH_NORMAL);
110 OSPango.pango_font_description_set_style(desc, style);
111 OSPango.pango_font_description_set_weight(desc, weight);
112 long attrList = OSPango.pango_attr_list_new();
113 if (check(attrList, "Failed allocating PangoAttributeList.", fontmap, context, desc, 0)) {
114 return;
115 }
116 long attr = OSPango.pango_attr_font_desc_new(desc);
117 if (check(attr, "Failed allocating PangoAttribute.", fontmap, context, desc, attrList)) {
118 return;
119 }
120 OSPango.pango_attr_list_insert(attrList, attr);
121 if (!composite) {
122 attr = OSPango.pango_attr_fallback_new(false);
123 OSPango.pango_attr_list_insert(attrList, attr);
124 }
125
126 if (str == 0L) {
127 str = OSPango.g_utf16_to_utf8(text);
128 if (check(str, "Failed allocating UTF-8 buffer.", fontmap, context, desc, attrList)) {
129 return;
130 }
131 }
132
133 /* Itemize */
134 long start = OSPango.g_utf8_offset_to_pointer(str, run.getStart());
135 long end = OSPango.g_utf8_offset_to_pointer(str, run.getEnd());
136 long runs = OSPango.pango_itemize(context, str, (int)(start - str), (int)(end - start), attrList, 0);
137
138 if (runs != 0) {
139 /* Shape all PangoItem into PangoGlyphString */
140 int runsCount = OSPango.g_list_length(runs);
141 PangoGlyphString[] pangoGlyphs = new PangoGlyphString[runsCount];
142 for (int i = 0; i < runsCount; i++) {
143 long pangoItem = OSPango.g_list_nth_data(runs, i);
144 if (pangoItem != 0) {
145 pangoGlyphs[i] = OSPango.pango_shape(str, pangoItem);
146 OSPango.pango_item_free(pangoItem);
147 }
148 }
173 * Note that Pango uses PANGO_GLYPH_EMPTY (0x0FFFFFFF), PANGO_GLYPH_INVALID_INPUT (0xFFFFFFFF),
174 * and other values with special meaning.
175 */
176 if (0 <= gg && gg <= CompositeGlyphMapper.GLYPHMASK) {
177 glyphs[gii] = (slot << 24) | gg;
178 }
179 }
180 if (size != 0) {
181 width += g.widths[i];
182 pos[2 + (gii << 1)] = ((float)width) / OSPango.PANGO_SCALE;
183 }
184 indices[gii] = g.log_clusters[i] + ci;
185 }
186 if (!rtl) ci += g.num_chars;
187 gi += g.num_glyphs;
188 }
189 }
190 run.shape(glyphCount, glyphs, pos, indices);
191 }
192
193 check(0, null, fontmap, context, desc, attrList);
194 }
195
196 @Override
197 public void dispose() {
198 super.dispose();
199 if (str != 0L) {
200 OSPango.g_free(str);
201 str = 0L;
202 }
203 }
204 }
|
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.javafx.font.freetype;
27
28 import com.sun.javafx.font.CompositeFontResource;
29 import com.sun.javafx.font.CompositeGlyphMapper;
30 import com.sun.javafx.font.FontResource;
31 import com.sun.javafx.font.FontStrike;
32 import com.sun.javafx.font.PGFont;
33 import com.sun.javafx.font.PrismFontFactory;
34 import com.sun.javafx.text.GlyphLayout;
35 import com.sun.javafx.text.TextRun;
36
37 class PangoGlyphLayout extends GlyphLayout {
38 private static long fontmap;
39
40 static {
41 fontmap = OSPango.pango_ft2_font_map_new();
42 }
43
44 private int getSlot(PGFont font, PangoGlyphString glyphString) {
45 CompositeFontResource fr = (CompositeFontResource)font.getFontResource();
46 long fallbackFont = glyphString.font;
47 long fallbackFd = OSPango.pango_font_describe(fallbackFont);
48 String fallbackFamily = OSPango.pango_font_description_get_family(fallbackFd);
49 int fallbackStyle = OSPango.pango_font_description_get_style(fallbackFd);
50 int fallbackWeight = OSPango.pango_font_description_get_weight(fallbackFd);
51 OSPango.pango_font_description_free(fallbackFd);
52 boolean bold = fallbackWeight == OSPango.PANGO_WEIGHT_BOLD;
53 boolean italic = fallbackStyle != OSPango.PANGO_STYLE_NORMAL;
54
55 PrismFontFactory prismFactory = PrismFontFactory.getFontFactory();
56 PGFont fallbackPGFont = prismFactory.createFont(fallbackFamily, bold,
57 italic, font.getSize());
58 String fallbackFullname = fallbackPGFont.getFullName();
59 String primaryFullname = fr.getSlotResource(0).getFullName();
60
61 int slot = 0;
62 if (!fallbackFullname.equalsIgnoreCase(primaryFullname)) {
63 slot = fr.getSlotForFont(fallbackFullname);
64 if (PrismFontFactory.debugFonts) {
65 System.err.println("\tFallback font= "+ fallbackFullname + " slot=" + (slot>>24));
66 }
67 }
68 return slot;
69 }
70
71 private boolean check(long checkValue, String message, long context, long desc, long attrList) {
72 if (checkValue != 0) return false;
73 if (message != null && PrismFontFactory.debugFonts) {
74 System.err.println(message);
75 }
76 /* pango_attr_list_unref() also frees the attributes it contains */
77 if (attrList != 0) OSPango.pango_attr_list_unref(attrList);
78 if (desc != 0) OSPango.pango_font_description_free(desc);
79 if (context != 0) OSPango.g_object_unref(context);
80 return true;
81 }
82
83 private long str = 0L;
84 public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
85
86 /* Create the pango font and attribute list */
87 FontResource fr = font.getFontResource();
88 boolean composite = fr instanceof CompositeFontResource;
89 if (composite) {
90 fr = ((CompositeFontResource)fr).getSlotResource(0);
91 }
92 if (check(fontmap, "Failed allocating PangoFontMap.", 0, 0, 0)) {
93 return;
94 }
95 long context = OSPango.pango_font_map_create_context(fontmap);
96 if (check(context, "Failed allocating PangoContext.", 0, 0, 0)) {
97 return;
98 }
99 boolean rtl = (run.getLevel() & 1) != 0;
100 if (rtl) {
101 OSPango.pango_context_set_base_dir(context, OSPango.PANGO_DIRECTION_RTL);
102 }
103 float size = font.getSize();
104 int style = fr.isItalic() ? OSPango.PANGO_STYLE_ITALIC : OSPango.PANGO_STYLE_NORMAL;
105 int weight = fr.isBold() ? OSPango.PANGO_WEIGHT_BOLD : OSPango.PANGO_WEIGHT_NORMAL;
106 long desc = OSPango.pango_font_description_new();
107 if (check(desc, "Failed allocating FontDescription.", context, 0, 0)) {
108 return;
109 }
110 OSPango.pango_font_description_set_family(desc, fr.getFamilyName());
111 OSPango.pango_font_description_set_absolute_size(desc, size * OSPango.PANGO_SCALE);
112 OSPango.pango_font_description_set_stretch(desc, OSPango.PANGO_STRETCH_NORMAL);
113 OSPango.pango_font_description_set_style(desc, style);
114 OSPango.pango_font_description_set_weight(desc, weight);
115 long attrList = OSPango.pango_attr_list_new();
116 if (check(attrList, "Failed allocating PangoAttributeList.", context, desc, 0)) {
117 return;
118 }
119 long attr = OSPango.pango_attr_font_desc_new(desc);
120 if (check(attr, "Failed allocating PangoAttribute.", context, desc, attrList)) {
121 return;
122 }
123 OSPango.pango_attr_list_insert(attrList, attr);
124 if (!composite) {
125 attr = OSPango.pango_attr_fallback_new(false);
126 OSPango.pango_attr_list_insert(attrList, attr);
127 }
128
129 if (str == 0L) {
130 str = OSPango.g_utf16_to_utf8(text);
131 if (check(str, "Failed allocating UTF-8 buffer.", context, desc, attrList)) {
132 return;
133 }
134 }
135
136 /* Itemize */
137 long start = OSPango.g_utf8_offset_to_pointer(str, run.getStart());
138 long end = OSPango.g_utf8_offset_to_pointer(str, run.getEnd());
139 long runs = OSPango.pango_itemize(context, str, (int)(start - str), (int)(end - start), attrList, 0);
140
141 if (runs != 0) {
142 /* Shape all PangoItem into PangoGlyphString */
143 int runsCount = OSPango.g_list_length(runs);
144 PangoGlyphString[] pangoGlyphs = new PangoGlyphString[runsCount];
145 for (int i = 0; i < runsCount; i++) {
146 long pangoItem = OSPango.g_list_nth_data(runs, i);
147 if (pangoItem != 0) {
148 pangoGlyphs[i] = OSPango.pango_shape(str, pangoItem);
149 OSPango.pango_item_free(pangoItem);
150 }
151 }
176 * Note that Pango uses PANGO_GLYPH_EMPTY (0x0FFFFFFF), PANGO_GLYPH_INVALID_INPUT (0xFFFFFFFF),
177 * and other values with special meaning.
178 */
179 if (0 <= gg && gg <= CompositeGlyphMapper.GLYPHMASK) {
180 glyphs[gii] = (slot << 24) | gg;
181 }
182 }
183 if (size != 0) {
184 width += g.widths[i];
185 pos[2 + (gii << 1)] = ((float)width) / OSPango.PANGO_SCALE;
186 }
187 indices[gii] = g.log_clusters[i] + ci;
188 }
189 if (!rtl) ci += g.num_chars;
190 gi += g.num_glyphs;
191 }
192 }
193 run.shape(glyphCount, glyphs, pos, indices);
194 }
195
196 check(0, null, context, desc, attrList);
197 }
198
199 @Override
200 public void dispose() {
201 super.dispose();
202 if (str != 0L) {
203 OSPango.g_free(str);
204 str = 0L;
205 }
206 }
207 }
|