Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / OT / Color / sbix / sbix.hh
similarity index 87%
rename from src/hb-ot-color-sbix-table.hh
rename to src/OT/Color/sbix/sbix.hh
index 9741ebd..ce8693c 100644 (file)
  * Google Author(s): Calder Kitagawa
  */
 
-#ifndef HB_OT_COLOR_SBIX_TABLE_HH
-#define HB_OT_COLOR_SBIX_TABLE_HH
+#ifndef OT_COLOR_SBIX_SBIX_HH
+#define OT_COLOR_SBIX_SBIX_HH
 
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
 
 /*
  * sbix -- Standard Bitmap Graphics
@@ -48,7 +48,6 @@ struct SBIXGlyph
   {
     TRACE_SERIALIZE (this);
     SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
-    if (unlikely (!new_glyph)) return_trace (nullptr);
     if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
 
     new_glyph->xOffset = xOffset;
@@ -143,7 +142,6 @@ struct SBIXStrike
     unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
 
     auto* out = c->serializer->start_embed<SBIXStrike> ();
-    if (unlikely (!out)) return_trace (false);
     auto snap = c->serializer->snapshot ();
     if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
     out->ppem = ppem;
@@ -213,10 +211,11 @@ struct sbix
 
     bool get_extents (hb_font_t          *font,
                      hb_codepoint_t      glyph,
-                     hb_glyph_extents_t *extents) const
+                     hb_glyph_extents_t *extents,
+                     bool                scale = true) const
     {
       /* We only support PNG right now, and following function checks type. */
-      return get_png_extents (font, glyph, extents);
+      return get_png_extents (font, glyph, extents, scale);
     }
 
     hb_blob_t *reference_png (hb_font_t      *font,
@@ -231,6 +230,37 @@ struct sbix
                                                  num_glyphs, available_ppem);
     }
 
+    bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      if (!has_data ())
+        return false;
+
+      int x_offset = 0, y_offset = 0;
+      unsigned int strike_ppem = 0;
+      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+      hb_glyph_extents_t extents;
+      hb_glyph_extents_t pixel_extents;
+
+      if (blob == hb_blob_get_empty ())
+        return false;
+
+      if (!hb_font_get_glyph_extents (font, glyph, &extents))
+        return false;
+
+      if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+        return false;
+
+      bool ret = funcs->image (data,
+                              blob,
+                              pixel_extents.width, -pixel_extents.height,
+                              HB_PAINT_IMAGE_FORMAT_PNG,
+                              font->slant_xy,
+                              &extents);
+
+      hb_blob_destroy (blob);
+      return ret;
+    }
+
     private:
 
     const SBIXStrike &choose_strike (hb_font_t *font) const
@@ -285,7 +315,8 @@ struct sbix
 
     bool get_png_extents (hb_font_t          *font,
                          hb_codepoint_t      glyph,
-                         hb_glyph_extents_t *extents) const
+                         hb_glyph_extents_t *extents,
+                         bool                scale = true) const
     {
       /* Following code is safe to call even without data.
        * But faster to short-circuit. */
@@ -298,28 +329,30 @@ struct sbix
 
       const PNGHeader &png = *blob->as<PNGHeader>();
 
+      if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536)
+      {
+       hb_blob_destroy (blob);
+       return false;
+      }
+
       extents->x_bearing = x_offset;
       extents->y_bearing = png.IHDR.height + y_offset;
       extents->width     = png.IHDR.width;
       extents->height    = -1 * png.IHDR.height;
 
       /* Convert to font units. */
-      if (strike_ppem)
+      if (strike_ppem && scale)
       {
        float scale = font->face->get_upem () / (float) strike_ppem;
-       extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale);
-       extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale);
-       extents->width = font->em_scalef_x (extents->width * scale);
-       extents->height = font->em_scalef_y (extents->height * scale);
-      }
-      else
-      {
-       extents->x_bearing = font->em_scale_x (extents->x_bearing);
-       extents->y_bearing = font->em_scale_y (extents->y_bearing);
-       extents->width = font->em_scale_x (extents->width);
-       extents->height = font->em_scale_y (extents->height);
+       extents->x_bearing = roundf (extents->x_bearing * scale);
+       extents->y_bearing = roundf (extents->y_bearing * scale);
+       extents->width = roundf (extents->width * scale);
+       extents->height = roundf (extents->height * scale);
       }
 
+      if (scale)
+       font->scale_glyph_extents (extents);
+
       hb_blob_destroy (blob);
 
       return strike_ppem;
@@ -353,7 +386,6 @@ struct sbix
     TRACE_SERIALIZE (this);
 
     auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
@@ -388,8 +420,6 @@ struct sbix
   {
     TRACE_SUBSET (this);
 
-    sbix *sbix_prime = c->serializer->start_embed<sbix> ();
-    if (unlikely (!sbix_prime)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
 
@@ -414,4 +444,4 @@ struct sbix_accelerator_t : sbix::accelerator_t {
 
 } /* namespace OT */
 
-#endif /* HB_OT_COLOR_SBIX_TABLE_HH */
+#endif /* OT_COLOR_SBIX_SBIX_HH */