< prev index next >

modules/javafx.graphics/src/main/java/com/sun/javafx/font/freetype/PangoGlyphLayout.java

Print this page




  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 }
< prev index next >