Re: The COLRv1 hook code (Re: FT_Bitmap and FT_BitmapGlyph life cycles)

2023-07-20 Thread Hin-Tak Leung
 On Thursday, 20 July 2023 at 09:04:09 BST, Brad Neimann 
 wrote:
 
 
 > > Perhaps it is easier just to show you what I have - this is already 
> > functional and I can even switch COLRv1 palettes in ftgrid 
> > (screenshots the usual place).

> …and where is this ‘usual place’? I can’t see screenshots anywhere.

They are being added to the bottom of:
https://github.com/HinTak/harfbuzz-python-demos/tree/master/skia-adventure

I have a COLRv1-emhanced ftgrid where the "C" key (normally for switching 
colours for glyph outlines in glyf mode) which cycles through the palettes - it 
also changes the status line on the side saying what palette number it is on.
Still on having freetype demos telling skia to do stuff and receiving rendered 
coloured bitmaps back :-). Just moving further on from skia rendering SVG to 
skia rendering COLRv1. Some of the 7 palettes are obviously for dark 
backgrounds - I probably should have this info out. How clear do you see things 
being interesting for palettes 0 to 6?  

Re: The COLRv1 hook code

2023-07-20 Thread Werner LEMBERG


> I'd like to not call "FT_Glyph_To_Bitmap()" but just do
> 'FT_New_Glyph()' on my own, but that always crashes.  Why?

What does the debugger say?  This might give a hint.

Are you sure that the memory allocation routine in your code is the
one used by FreeType?  `FT_MEM_ALLOC` is an internal function...


Werner



Re: The COLRv1 hook code (Re: FT_Bitmap and FT_BitmapGlyph life cycles)

2023-07-20 Thread Brad Neimann
> Perhaps it is easier just to show you what I have - this is already 
> functional and I can even switch COLRv1 palettes in ftgrid 
> (screenshots the usual place).

…and where is this ‘usual place’? I can’t see screenshots anywhere.

Regards,
Brad



The COLRv1 hook code (Re: FT_Bitmap and FT_BitmapGlyph life cycles)

2023-07-19 Thread Hin-Tak Leung
 Perhaps it is easier just to show you what I have - this is already functional 
and I can even switch COLRv1 palettes in ftgrid (screenshots the usual place). 
Basically it works the same ways as svg hooks: the preset slot hook calculates 
the bound boxes, while the render hook actually draws to the bitmap.

In this case, I have a FT_Load_Glyph_Extended() which calls FT_Load_Glyph(), 
but also call FT_Get_Color_Glyph_ClipBox_Extended(), which is a skia routine 
which does FT_Get_Color_Glyph_ClipBox() but also if that fails, tries to union 
all the layers to calculate a skia bound box. I should convert back to override 
the FT_Load_Glyph() bound values but haven't (yet).


Then I have a "FT_Glyph_To_Bitmap_Extended()" which also calls 
"FT_Glyph_To_Bitmap()", but then overwrite and draws to its bitmap with skia 
before returning. I'd like to not call "FT_Glyph_To_Bitmap()" but just do 
'FT_New_Glyph()' on my own, but that always crashes. why?

'...' and '...' are deleted parts too ugly that will hurt your eyes if you see 
them :-).  #include "skia-colrv1-stub.h"
#include FT_COLOR_H
#include FT_BITMAP_H
#include "include/core/SkRect.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "freetype/internal/ftobjs.h"
#include "skia-src-ports-SkFontHost_FreeType_common_colrv1.h"

/* in skia-src-ports-SkFontHost_FreeType_colrv1.cpp */
SkRect FT_Get_Color_Glyph_ClipBox_Extended( FT_Face  fFace,
FT_UInt  base_glyph,
FT_ClipBox*  clip_box );

FT_Bool isCOLRv1(FT_Face   face,
 FT_UInt   glyph_index) {
  if (FT_IS_SCALABLE(face)) {
FT_OpaquePaint opaqueLayerPaint{nullptr, 1};
if (FT_Get_Color_Glyph_Paint(face, glyph_index,
 FT_COLOR_INCLUDE_ROOT_TRANSFORM, )) {
  return true;
}
  }
  return false;
}

void skia_colr_set_current_palette( FT_Face   face,
FT_UInt   palette_index ) {
  ... = ... palette_index;
}

FT_UShort skia_colr_get_current_palette( FT_Face   face ) {
  ... ;
}

FT_Error FT_Load_Glyph_Extended( FT_Face   face,
 FT_UInt   glyph_index,
 FT_Int32  load_flags ) {
  if ( isCOLRv1( face, glyph_index)
   && (load_flags & FT_LOAD_COLOR)
   ) {

FT_ClipBox clipBox;
SkRect bounds = FT_Get_Color_Glyph_ClipBox_Extended( face,
 glyph_index,
  );
   ... keep bounds ...
  }

  FT_Error res = FT_Load_Glyph( face, glyph_index, load_flags );
  return res;
}

FT_Error FT_Glyph_To_Bitmap_Extended( FT_Glyph* the_glyph,
  FT_Render_Moderender_mode,
  const FT_Vector*  origin,
  FT_Bool   destroy ) {
   ...
  FT_Error res = FT_Glyph_To_Bitmap( the_glyph, render_mode, origin, destroy );

   ... retrieve bounds ...

  if ( face && bounds ) {
  FT_UInt  glyph_index = face->glyph->glyph_index;
/* General variables. */
int width  = ceil(bounds->right()) - floor(bounds->left()); //bounds.width();  // fRight minus fLeft
int height = ceil(bounds->bottom()) - floor(bounds->top()); //bounds.height(); // fBottom minus fTop
int x = floor(bounds->left());
int y = floor(bounds->top());

int size = width * height * 4;

FT_Error   error;
FT_Memory  memory  = lib->memory;
FT_Glyphgbitmap = NULL;

if (isCOLRv1(face, glyph_index) && (FT_GLYPH_FORMAT_BITMAP == (*the_glyph)->format))
  {
FT_BitmapGlyphbitmap = (FT_BitmapGlyph)(*the_glyph);
if ((bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) || (bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)) {

  SkBitmap dstBitmap;
  dstBitmap.setInfo(SkImageInfo::Make(bitmap->bitmap.width, bitmap->bitmap.rows,
  ((bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) ?
   kBGRA__SkColorType : kGray_8_SkColorType),
  kPremul_SkAlphaType),
bitmap->bitmap.pitch);
  dstBitmap.setPixels(bitmap->bitmap.buffer);
  SkCanvas canvas(dstBitmap);
  canvas.clear(SK_ColorTRANSPARENT);
  canvas.translate( -x, -y );
  bool haveLayers =  skia_colrv1_start_glyph(,
 face, glyph_index,
 FT_COLOR_INCLUDE_ROOT_TRANSFORM);
  fprintf(stderr, "**bounds %d %d %d %d - SkRect Max\n",
  x,
  -y,
  width,
  height);
  fprintf(stderr, "**bounds %d %d %d %d - Not skia\n",
  bitmap->left,