< prev index next >

src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc

Print this page




  25 
  26 #include "jlong.h"
  27 #include "sun_font_SunLayoutEngine.h"
  28 
  29 #include "hb.h"
  30 #include "hb-jdk.h"
  31 #ifdef MACOSX
  32 #include "hb-coretext.h"
  33 #endif
  34 #include <stdlib.h>
  35 
  36 #if defined(__GNUC__) &&  __GNUC__ >= 4
  37 #define HB_UNUSED       __attribute__((unused))
  38 #else
  39 #define HB_UNUSED
  40 #endif
  41 
  42 
  43 static hb_bool_t
  44 hb_jdk_get_nominal_glyph (hb_font_t *font HB_UNUSED,
  45                           void *font_data,
  46                           hb_codepoint_t unicode,
  47                           hb_codepoint_t *glyph,
  48                           void *user_data HB_UNUSED)
  49 {
  50 
  51     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
  52     JNIEnv* env = jdkFontInfo->env;
  53     jobject font2D = jdkFontInfo->font2D;
  54     *glyph = (hb_codepoint_t)env->CallIntMethod(
  55               font2D, sunFontIDs.f2dCharToGlyphMID, unicode);
  56     if (env->ExceptionOccurred())
  57     {
  58         env->ExceptionClear();
  59     }
  60     if ((int)*glyph < 0) {
  61         *glyph = 0;
  62     }
  63     return (*glyph != 0);
  64 }
  65 
  66 static hb_bool_t
  67 hb_jdk_get_variation_glyph (hb_font_t *font HB_UNUSED,
  68                  void *font_data,
  69                  hb_codepoint_t unicode,
  70                  hb_codepoint_t variation_selector,
  71                  hb_codepoint_t *glyph,
  72                  void *user_data HB_UNUSED)
  73 {
  74 
  75     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
  76     JNIEnv* env = jdkFontInfo->env;
  77     jobject font2D = jdkFontInfo->font2D;
  78     *glyph = (hb_codepoint_t)env->CallIntMethod(
  79               font2D, sunFontIDs.f2dCharToVariationGlyphMID, 
  80               unicode, variation_selector);
  81     if (env->ExceptionOccurred())
  82     {
  83         env->ExceptionClear();
  84     }
  85     if ((int)*glyph < 0) {
  86         *glyph = 0;
  87     }
  88     return (*glyph != 0);
  89 }
  90 
  91 static hb_position_t
  92 hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
  93                            void *font_data,
  94                            hb_codepoint_t glyph,
  95                            void *user_data HB_UNUSED)
  96 {
  97 
  98     float fadv = 0.0f;
  99     if ((glyph & 0xfffe) == 0xfffe) {
 100         return 0; // JDK uses this glyph code.
 101     }
 102 
 103     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 104     JNIEnv* env = jdkFontInfo->env;
 105     jobject fontStrike = jdkFontInfo->fontStrike;
 106     jobject pt = env->CallObjectMethod(fontStrike,
 107                                        sunFontIDs.getGlyphMetricsMID, glyph);
 108 
 109     if (pt == NULL) {
 110         return 0;
 111     }
 112     fadv = env->GetFloatField(pt, sunFontIDs.xFID);
 113     fadv *= jdkFontInfo->devScale;
 114     env->DeleteLocalRef(pt);
 115 
 116     return HBFloatToFixed(fadv);
 117 }
 118 
 119 static hb_position_t
 120 hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 121                            void *font_data,
 122                            hb_codepoint_t glyph,
 123                            void *user_data HB_UNUSED)
 124 {
 125 
 126     float fadv = 0.0f;
 127     if ((glyph & 0xfffe) == 0xfffe) {
 128         return 0; // JDK uses this glyph code.
 129     }
 130 
 131     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 132     JNIEnv* env = jdkFontInfo->env;
 133     jobject fontStrike = jdkFontInfo->fontStrike;
 134     jobject pt = env->CallObjectMethod(fontStrike,
 135                                        sunFontIDs.getGlyphMetricsMID, glyph);
 136 
 137     if (pt == NULL) {
 138         return 0;
 139     }
 140     fadv = env->GetFloatField(pt, sunFontIDs.yFID);
 141     env->DeleteLocalRef(pt);
 142 
 143     return HBFloatToFixed(fadv);
 144 
 145 }
 146 
 147 static hb_bool_t
 148 hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
 149                           void *font_data HB_UNUSED,
 150                           hb_codepoint_t glyph HB_UNUSED,
 151                           hb_position_t *x HB_UNUSED,
 152                           hb_position_t *y HB_UNUSED,
 153                           void *user_data HB_UNUSED)
 154 {
 155   /* We always work in the horizontal coordinates. */
 156   return true;
 157 }
 158 
 159 static hb_bool_t
 160 hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
 161                           void *font_data,
 162                           hb_codepoint_t glyph,
 163                           hb_position_t *x,
 164                           hb_position_t *y,
 165                           void *user_data HB_UNUSED)
 166 {
 167   return false;
 168 }
 169 
 170 static hb_position_t
 171 hb_jdk_get_glyph_h_kerning (hb_font_t *font,
 172                            void *font_data,
 173                            hb_codepoint_t lejdk_glyph,
 174                            hb_codepoint_t right_glyph,
 175                            void *user_data HB_UNUSED)
 176 {
 177   /* Not implemented. This seems to be in the HB API
 178    * as a way to fall back to Freetype's kerning support
 179    * which could be based on some on-the fly glyph analysis.
 180    * But more likely it reads the kern table. That is easy
 181    * enough code to add if we find a need to fall back
 182    * to that instead of using gpos. It seems like if
 183    * there is a gpos table at all, the practice is to
 184    * use that and ignore kern, no matter that gpos does
 185    * not implement the kern feature.
 186    */
 187   return 0;
 188 }
 189 
 190 static hb_position_t
 191 hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
 192                            void *font_data HB_UNUSED,
 193                            hb_codepoint_t top_glyph HB_UNUSED,
 194                            hb_codepoint_t bottom_glyph HB_UNUSED,
 195                            void *user_data HB_UNUSED)
 196 {
 197   /* OpenType doesn't have vertical-kerning other than GPOS. */
 198   return 0;
 199 }
 200 
 201 static hb_bool_t
 202 hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
 203                          void *font_data,
 204                          hb_codepoint_t glyph,
 205                          hb_glyph_extents_t *extents,
 206                          void *user_data HB_UNUSED)
 207 {
 208   /* TODO */
 209   return false;
 210 }
 211 
 212 static hb_bool_t
 213 hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
 214                                void *font_data,
 215                                hb_codepoint_t glyph,
 216                                unsigned int point_index,
 217                                hb_position_t *x,
 218                                hb_position_t *y,
 219                                void *user_data HB_UNUSED)
 220 {
 221     if ((glyph & 0xfffe) == 0xfffe) {
 222         *x = 0; *y = 0;
 223         return true;
 224     }
 225 
 226     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 227     JNIEnv* env = jdkFontInfo->env;
 228     jobject fontStrike = jdkFontInfo->fontStrike;
 229     jobject pt = env->CallObjectMethod(fontStrike,
 230                                        sunFontIDs.getGlyphPointMID,
 231                                        glyph, point_index);
 232 
 233     if (pt == NULL) {
 234         *x = 0; *y = 0;
 235         return true;
 236     }
 237     *x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
 238     *y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
 239     env->DeleteLocalRef(pt);
 240 
 241   return true;
 242 }
 243 
 244 static hb_bool_t
 245 hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
 246                       void *font_data,
 247                       hb_codepoint_t glyph,
 248                       char *name, unsigned int size,
 249                       void *user_data HB_UNUSED)
 250 {
 251   return false;
 252 }
 253 
 254 static hb_bool_t
 255 hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
 256                            void *font_data,
 257                            const char *name, int len,
 258                            hb_codepoint_t *glyph,
 259                            void *user_data HB_UNUSED)
 260 {
 261   return false;
 262 }
 263 
 264 // remind : can we initialise this from the code we call
 265 // from the class static method in Java to make it
 266 // completely thread safe.
 267 static hb_font_funcs_t *
 268 _hb_jdk_get_font_funcs (void)
 269 {
 270   static hb_font_funcs_t *jdk_ffuncs = NULL;
 271   hb_font_funcs_t *ff;
 272 
 273   if (!jdk_ffuncs) {
 274       ff = hb_font_funcs_create();
 275 
 276       hb_font_funcs_set_nominal_glyph_func(ff, hb_jdk_get_nominal_glyph, NULL, NULL);
 277       hb_font_funcs_set_variation_glyph_func(ff, hb_jdk_get_variation_glyph, NULL, NULL);
 278       hb_font_funcs_set_glyph_h_advance_func(ff,
 279                     hb_jdk_get_glyph_h_advance, NULL, NULL);




  25 
  26 #include "jlong.h"
  27 #include "sun_font_SunLayoutEngine.h"
  28 
  29 #include "hb.h"
  30 #include "hb-jdk.h"
  31 #ifdef MACOSX
  32 #include "hb-coretext.h"
  33 #endif
  34 #include <stdlib.h>
  35 
  36 #if defined(__GNUC__) &&  __GNUC__ >= 4
  37 #define HB_UNUSED       __attribute__((unused))
  38 #else
  39 #define HB_UNUSED
  40 #endif
  41 
  42 
  43 static hb_bool_t
  44 hb_jdk_get_nominal_glyph (hb_font_t *font HB_UNUSED,
  45                           void *font_data,
  46                           hb_codepoint_t unicode,
  47                           hb_codepoint_t *glyph,
  48                           void *user_data HB_UNUSED)
  49 {
  50 
  51     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
  52     JNIEnv* env = jdkFontInfo->env;
  53     jobject font2D = jdkFontInfo->font2D;
  54     *glyph = (hb_codepoint_t)env->CallIntMethod(
  55               font2D, sunFontIDs.f2dCharToGlyphMID, unicode);
  56     if (env->ExceptionOccurred())
  57     {
  58         env->ExceptionClear();
  59     }
  60     if ((int)*glyph < 0) {
  61         *glyph = 0;
  62     }
  63     return (*glyph != 0);
  64 }
  65 
  66 static hb_bool_t
  67 hb_jdk_get_variation_glyph (hb_font_t *font HB_UNUSED,
  68                  void *font_data,
  69                  hb_codepoint_t unicode,
  70                  hb_codepoint_t variation_selector,
  71                  hb_codepoint_t *glyph,
  72                  void *user_data HB_UNUSED)
  73 {
  74 
  75     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
  76     JNIEnv* env = jdkFontInfo->env;
  77     jobject font2D = jdkFontInfo->font2D;
  78     *glyph = (hb_codepoint_t)env->CallIntMethod(
  79               font2D, sunFontIDs.f2dCharToVariationGlyphMID,
  80               unicode, variation_selector);
  81     if (env->ExceptionOccurred())
  82     {
  83         env->ExceptionClear();
  84     }
  85     if ((int)*glyph < 0) {
  86         *glyph = 0;
  87     }
  88     return (*glyph != 0);
  89 }
  90 
  91 static hb_position_t
  92 hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
  93                            void *font_data,
  94                            hb_codepoint_t glyph,
  95                            void *user_data HB_UNUSED)
  96 {
  97 
  98     float fadv = 0.0f;
  99     if ((glyph & 0xfffe) == 0xfffe) {
 100         return 0; // JDK uses this glyph code.
 101     }
 102 
 103     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 104     JNIEnv* env = jdkFontInfo->env;
 105     jobject fontStrike = jdkFontInfo->fontStrike;
 106     jobject pt = env->CallObjectMethod(fontStrike,
 107                                        sunFontIDs.getGlyphMetricsMID, glyph);
 108 
 109     if (pt == NULL) {
 110         return 0;
 111     }
 112     fadv = env->GetFloatField(pt, sunFontIDs.xFID);
 113     fadv *= jdkFontInfo->devScale;
 114     env->DeleteLocalRef(pt);
 115 
 116     return HBFloatToFixed(fadv);
 117 }
 118 
 119 static hb_position_t
 120 hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 121                            void *font_data,
 122                            hb_codepoint_t glyph,
 123                            void *user_data HB_UNUSED)
 124 {
 125 
 126     float fadv = 0.0f;
 127     if ((glyph & 0xfffe) == 0xfffe) {
 128         return 0; // JDK uses this glyph code.
 129     }
 130 
 131     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 132     JNIEnv* env = jdkFontInfo->env;
 133     jobject fontStrike = jdkFontInfo->fontStrike;
 134     jobject pt = env->CallObjectMethod(fontStrike,
 135                                        sunFontIDs.getGlyphMetricsMID, glyph);
 136 
 137     if (pt == NULL) {
 138         return 0;
 139     }
 140     fadv = env->GetFloatField(pt, sunFontIDs.yFID);
 141     env->DeleteLocalRef(pt);
 142 
 143     return HBFloatToFixed(fadv);
 144 
 145 }
 146 
 147 static hb_bool_t
 148 hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
 149                           void *font_data HB_UNUSED,
 150                           hb_codepoint_t glyph HB_UNUSED,
 151                           hb_position_t *x HB_UNUSED,
 152                           hb_position_t *y HB_UNUSED,
 153                           void *user_data HB_UNUSED)
 154 {
 155   /* We always work in the horizontal coordinates. */
 156   return true;
 157 }
 158 
 159 static hb_bool_t
 160 hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
 161                           void *font_data,
 162                           hb_codepoint_t glyph,
 163                           hb_position_t *x,
 164                           hb_position_t *y,
 165                           void *user_data HB_UNUSED)
 166 {
 167   return false;
 168 }
 169 
 170 static hb_position_t
 171 hb_jdk_get_glyph_h_kerning (hb_font_t *font,
 172                            void *font_data,
 173                            hb_codepoint_t lejdk_glyph,
 174                            hb_codepoint_t right_glyph,
 175                            void *user_data HB_UNUSED)
 176 {
 177   /* Not implemented. This seems to be in the HB API
 178    * as a way to fall back to Freetype's kerning support
 179    * which could be based on some on-the fly glyph analysis.
 180    * But more likely it reads the kern table. That is easy
 181    * enough code to add if we find a need to fall back
 182    * to that instead of using gpos. It seems like if
 183    * there is a gpos table at all, the practice is to
 184    * use that and ignore kern, no matter that gpos does
 185    * not implement the kern feature.
 186    */
 187   return 0;
 188 }
 189 
 190 static hb_position_t
 191 hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
 192                            void *font_data HB_UNUSED,
 193                            hb_codepoint_t top_glyph HB_UNUSED,
 194                            hb_codepoint_t bottom_glyph HB_UNUSED,
 195                            void *user_data HB_UNUSED)
 196 {
 197   /* OpenType doesn't have vertical-kerning other than GPOS. */
 198   return 0;
 199 }
 200 
 201 static hb_bool_t
 202 hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
 203                          void *font_data,
 204                          hb_codepoint_t glyph,
 205                          hb_glyph_extents_t *extents,
 206                          void *user_data HB_UNUSED)
 207 {
 208   /* TODO */
 209   return false;
 210 }
 211 
 212 static hb_bool_t
 213 hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
 214                                void *font_data,
 215                                hb_codepoint_t glyph,
 216                                unsigned int point_index,
 217                                hb_position_t *x,
 218                                hb_position_t *y,
 219                                void *user_data HB_UNUSED)
 220 {
 221     if ((glyph & 0xfffe) == 0xfffe) {
 222         *x = 0; *y = 0;
 223         return true;
 224     }
 225 
 226     JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
 227     JNIEnv* env = jdkFontInfo->env;
 228     jobject fontStrike = jdkFontInfo->fontStrike;
 229     jobject pt = env->CallObjectMethod(fontStrike,
 230                                        sunFontIDs.getGlyphPointMID,
 231                                        glyph, point_index);
 232 
 233     if (pt == NULL) {
 234         *x = 0; *y = 0;
 235         return true;
 236     }
 237     *x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
 238     *y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
 239     env->DeleteLocalRef(pt);
 240 
 241   return true;
 242 }
 243 
 244 static hb_bool_t
 245 hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
 246                       void *font_data,
 247                       hb_codepoint_t glyph,
 248                       char *name, unsigned int size,
 249                       void *user_data HB_UNUSED)
 250 {
 251   return false;
 252 }
 253 
 254 static hb_bool_t
 255 hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
 256                            void *font_data,
 257                            const char *name, int len,
 258                            hb_codepoint_t *glyph,
 259                            void *user_data HB_UNUSED)
 260 {
 261   return false;
 262 }
 263 
 264 // remind : can we initialise this from the code we call
 265 // from the class static method in Java to make it
 266 // completely thread safe.
 267 static hb_font_funcs_t *
 268 _hb_jdk_get_font_funcs (void)
 269 {
 270   static hb_font_funcs_t *jdk_ffuncs = NULL;
 271   hb_font_funcs_t *ff;
 272 
 273   if (!jdk_ffuncs) {
 274       ff = hb_font_funcs_create();
 275 
 276       hb_font_funcs_set_nominal_glyph_func(ff, hb_jdk_get_nominal_glyph, NULL, NULL);
 277       hb_font_funcs_set_variation_glyph_func(ff, hb_jdk_get_variation_glyph, NULL, NULL);
 278       hb_font_funcs_set_glyph_h_advance_func(ff,
 279                     hb_jdk_get_glyph_h_advance, NULL, NULL);


< prev index next >