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,