[ot-color/png] Implement CBDT part
authorEbrahim Byagowi <ebrahim@gnu.org>
Sat, 27 Oct 2018 10:02:14 +0000 (13:32 +0330)
committerEbrahim Byagowi <ebrahim@gnu.org>
Sat, 27 Oct 2018 10:17:11 +0000 (13:47 +0330)
src/hb-ot-color-cbdt-table.hh
src/hb-ot-color.cc
src/hb-ot-color.h
test/api/test-ot-color.c

index 770fe3e..a9518b7 100644 (file)
@@ -504,12 +504,58 @@ struct CBDT
       }
     }
 
-    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id HB_UNUSED,
-                                               unsigned int    requested_x_ppem HB_UNUSED,
-                                               unsigned int    requested_y_ppem HB_UNUSED,
-                                               unsigned int   *strike_x_ppem HB_UNUSED,
-                                               unsigned int   *strike_y_ppem HB_UNUSED) const
+    inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t  glyph_id,
+                                               unsigned int    requested_x_ppem,
+                                               unsigned int    requested_y_ppem,
+                                               unsigned int   *strike_x_ppem,
+                                               unsigned int   *strike_y_ppem) const
     {
+      if (!cblc)
+       return hb_blob_get_empty ();  // Not a color bitmap font.
+
+      if (requested_x_ppem == 0) requested_x_ppem = upem;
+      if (requested_y_ppem == 0) requested_y_ppem = upem;
+      unsigned int x_ppem = requested_x_ppem, y_ppem = requested_y_ppem;
+
+      const void *base;
+      const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base);
+      if (!subtable_record || !x_ppem || !y_ppem)
+       return hb_blob_get_empty ();
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph_id, base, &image_offset, &image_length, &image_format))
+       return hb_blob_get_empty ();
+
+      switch (image_format)
+      {
+      case 17: {
+       if (strike_x_ppem) *strike_x_ppem = x_ppem;
+       if (strike_x_ppem) *strike_y_ppem = y_ppem;
+       const GlyphBitmapDataFormat17& glyphFormat17 =
+          StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+       return hb_blob_create_sub_blob (cbdt_blob,
+                                       image_offset + GlyphBitmapDataFormat17::min_size,
+                                       glyphFormat17.data.len);
+      }
+      case 18: {
+       if (strike_x_ppem) *strike_x_ppem = x_ppem;
+       if (strike_x_ppem) *strike_y_ppem = y_ppem;
+       const GlyphBitmapDataFormat18& glyphFormat18 =
+          StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+       return hb_blob_create_sub_blob (cbdt_blob,
+                                       image_offset + GlyphBitmapDataFormat18::min_size,
+                                       glyphFormat18.data.len);
+      }
+      case 19: {
+       if (strike_x_ppem) *strike_x_ppem = x_ppem;
+       if (strike_x_ppem) *strike_y_ppem = y_ppem;
+       const GlyphBitmapDataFormat19& glyphFormat19 =
+          StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+       return hb_blob_create_sub_blob (cbdt_blob,
+                                       image_offset + GlyphBitmapDataFormat19::min_size,
+                                       glyphFormat19.data.len);
+      }
+      }
       return hb_blob_get_empty ();
     }
 
index 8dd3b2a..9de2f9a 100644 (file)
@@ -75,22 +75,6 @@ _get_svg (hb_face_t *face)
   return *(hb_ot_face_data (face)->SVG.get ());
 }
 
-#if 0
-static inline const OT::CBDT_accelerator_t&
-_get_cbdt (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t);
-  return *(hb_ot_face_data (face)->CBDT.get ());
-}
-
-static inline const OT::sbix&
-_get_sbix (hb_face_t *face)
-{
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix);
-  return *(hb_ot_face_data (face)->sbix.get ());
-}
-#endif
-
 
 /*
  * CPAL
@@ -289,7 +273,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph)
 
 
 /*
- * PNG, CBDT or sbix
+ * PNG: CBDT or sbix
  */
 
 /**
@@ -335,4 +319,5 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t      *font,
                                                            HB_TAG('p','n','g',' '),
                                                            strike_x_ppem, strike_y_ppem);
 
+  return hb_blob_get_empty ();
 }
index 7901a35..1810cd6 100644 (file)
@@ -121,6 +121,10 @@ hb_ot_color_has_svg (hb_face_t *face);
 HB_EXTERN hb_blob_t *
 hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph);
 
+/*
+ * PNG: CBDT or sbix
+ */
+
 HB_EXTERN hb_bool_t
 hb_ot_color_has_png (hb_face_t *face);
 
index 767a3d6..51b901d 100644 (file)
@@ -405,22 +405,41 @@ static void
 test_hb_ot_color_png (void)
 {
   hb_blob_t *blob;
+  unsigned int length;
+  const char *data;
+  unsigned int strike_x_ppem, strike_y_ppem;
 
+  /* sbix */
   hb_font_t *sbix_font;
   sbix_font = hb_font_create (sbix);
   blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL);
   g_assert (hb_blob_get_length (blob) == 0);
 
-  unsigned int strike_x_ppem, strike_y_ppem;
   blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1,
                                               &strike_x_ppem, &strike_y_ppem);
-  unsigned int length;
-  const char *data = hb_blob_get_data (blob, &length);
+  data = hb_blob_get_data (blob, &length);
   g_assert_cmpuint (length, ==, 224);
   g_assert_cmpuint (strike_x_ppem, ==, 300);
   g_assert_cmpuint (strike_y_ppem, ==, 300);
   g_assert (strncmp (data + 1, "PNG", 3) == 0);
   hb_blob_destroy (blob);
+  hb_font_destroy (sbix_font);
+
+  /* cbdt */
+  hb_font_t *cbdt_font;
+  cbdt_font = hb_font_create (cbdt);
+  blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0, NULL, NULL);
+  g_assert (hb_blob_get_length (blob) == 0);
+
+  blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1,
+                                              &strike_x_ppem, &strike_y_ppem);
+  data = hb_blob_get_data (blob, &length);
+  g_assert_cmpuint (length, ==, 88);
+  g_assert_cmpuint (strike_x_ppem, ==, 80);
+  g_assert_cmpuint (strike_y_ppem, ==, 80);
+  g_assert (strncmp (data + 1, "PNG", 3) == 0);
+  hb_blob_destroy (blob);
+  hb_font_destroy (cbdt_font);
 }
 
 int