void ft_put_pixel_to_image(t_img img, int x, int y, t_color3 color) { int addr; addr = y * img.sizeline + x * (img.bpp / 8); img.data[addr + 0] = FT_MAX(FT_MIN(color.b * 255, 255), 0); img.data[addr + 1] = FT_MAX(FT_MIN(color.g * 255, 255), 0); img.data[addr + 2] = FT_MAX(FT_MIN(color.r * 255, 255), 0); }
void writes_str(const char *s, t_printf_arg *a) { size_t i; size_t j; size_t size; size = ft_strlen(s); size = (a->prec.right != -1) ? FT_MIN((size_t)a->prec.right, size) : size; a->size = FT_MAX((int)size, a->prec.left); if (!(a->buf = ft_strnew(a->size))) return ; if ((i = -1) && !s && !(a->flags & deci)) return ((void)(ft_memcpy(a->buf, "(null)", (a->size = 6)))); if (!(j = 0) && !(a->flags & less)) { while (++i < a->size - size) a->buf[i] = (!(a->flags & zero)) ? ' ' : '0'; while (i < a->size) a->buf[i++] = s[j++]; } else { while (++i < size) a->buf[i] = s[i]; while (i < a->size) a->buf[i++] = ' '; } }
static int check_list(t_fdf *e, t_list **list) { int i; int j; t_list *tmp; if (!(tmp = my_first_init(e, list, &i))) return (0); while ((j = -1) && tmp) { if (!(e->p[--i] = (t_3d *)malloc((e->npw + 1) * sizeof(t_3d)))) { ft_lstdel(list, &my_lstdel); return (0); } while (((char **)tmp->content)[++j]) { e->p[i][j].z = ft_atoi(((char **)tmp->content)[j]); e->mia = FT_MIN(e->mia, e->p[i][j].z); e->maa = FT_MAX(e->maa, e->p[i][j].z); } while (j < e->npw) e->p[i][j++].z = 0; tmp = tmp->next; } ft_lstdel(list, &my_lstdel); return (1); }
void writes_wintt(wchar_t c, t_printf_arg *arg) { size_t i; size_t size; size_t size2; size = (arg->prec.right > 0) ? FT_MIN(arg->prec.right, 1) : 1; size2 = FT_MAX((int)size, arg->prec.left); i = -1; if (!(arg->buf = ft_strnew(size2 * 4))) return ; if (!(arg->flags & less)) { while (++i < size2 - size) arg->buf[arg->size++] = (!(arg->flags & zero)) ? ' ' : '0'; add_char(c, arg); } else { if (c && i++) add_char(c, arg); while (++i < size2) arg->buf[arg->size++] = ' '; } if (!arg->size) arg->size = 1; }
static void gxv_mort_subtable_type1_offset_to_subst_validate( FT_Short wordOffset, const FT_String* tag, FT_Byte state, GXV_Validator valid ) { FT_UShort substTable; FT_UShort substTable_limit; FT_UShort min_gid; FT_UShort max_gid; FT_UNUSED( tag ); FT_UNUSED( state ); substTable = ((GXV_mort_subtable_type1_StateOptRec *) (valid->statetable.optdata))->substitutionTable; substTable_limit = (FT_UShort)( substTable + ((GXV_mort_subtable_type1_StateOptRec *) (valid->statetable.optdata))->substitutionTable_length ); min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 ); max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 ); max_gid = (FT_UShort)( FT_MAX( max_gid, valid->face->num_glyphs ) ); /* XXX: check range? */ /* TODO: min_gid & max_gid comparison with ClassTable contents */ }
void writes_uchar(unsigned char c, t_printf_arg *arg) { size_t i; size_t size; size = (arg->prec.right > 0) ? FT_MIN(arg->prec.right, 1) : 1; arg->size = FT_MAX((int)size, arg->prec.left); i = -1; if (!(arg->buf = ft_strnew(arg->size))) return ; if (!(arg->flags & less)) { while (++i < arg->size - size) arg->buf[i] = (!(arg->flags & zero)) ? ' ' : '0'; arg->buf[i] = c; } else { arg->buf[++i] = c; while (++i < arg->size) arg->buf[i] = ' '; } if (!arg->size) arg->size = 1; }
static t_list *my_first_init(t_fdf *e, t_list **list, int *size) { int i; t_list *tmp; e->nph = 0; tmp = *list; while (tmp) { i = 0; while (((char **)(tmp->content))[i]) i++; e->npw = FT_MAX(e->npw, i); tmp = tmp->next; e->nph++; } if (!(e->p = (t_3d **)malloc((e->nph + 1) * sizeof(t_3d *)))) { ft_lstdel(list, &my_lstdel); return (NULL); } i = 0; *size = e->nph; while (i <= *size) e->p[i++] = NULL; return (*list); }
static inline int init(uintmax_t nbr, t_pfflags *flags) { return ((int)((FT_BIT_VAL(flags->flg, FTPF_PRECISION) ? FT_MAX(flags->n_digits, flags->prec) : flags->n_digits) + ((nbr || FT_BIT_VAL(flags->flg, FTPF_FORCE_PREFIX_)) && FT_BIT_VAL(flags->flg, FTPF_PREFIX) ? FT_T((flags->base == 8) || (flags->base == 16), (flags->base == 8) + 2 * (flags->base == 16), (flags->base > 9) + 2) : 0))); }
float calc_lights(t_line p, t_list *lights, float scene_ambl, float elem_l) { float light; t_light *ls; // return (p.o.x / 10); if (lights == NULL) return (FT_MAX(scene_ambl, elem_l)); ls = (t_light*)lights->content; light = geo_scalar_produce(p.v, geo_vector_pp(p.o, ls->position)) / geo_vector_norme(p.v) / geo_vector_norme(geo_vector_pp(p.o, ls->position)); if (light < elem_l) light = elem_l; if (light < scene_ambl) light = scene_ambl; return (light); }
void writes_wstr(const wchar_t *str, t_printf_arg *arg) { size_t sizes[4]; sizes[1] = 0; if (str) while (str[sizes[1]]) sizes[1]++; sizes[3] = ft_wstrlen(str, sizes[1], INT_MAX); sizes[3] = (arg->prec.right != -1) ? FT_MIN((int)ft_wstrlen(str, INT_MAX, arg->prec.right), (int)(sizes[3])) : (int)sizes[3]; sizes[2] = FT_MAX((int)(sizes[3]), arg->prec.left); if (!(arg->buf = ft_strnew(sizes[2] * 4))) return ; if (!str && !(arg->flags & deci)) return ((void)(ft_memcpy(arg->buf, "(null)", (arg->size = 6)))); wstr_less_or_not(str, arg, sizes); }
ft_lcd_padding( FT_BBox* cbox, FT_GlyphSlot slot, FT_Render_Mode mode ) { FT_Vector* sub = slot->library->lcd_geometry; if ( mode == FT_RENDER_MODE_LCD ) { cbox->xMin -= FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x ); cbox->xMax -= FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x ); cbox->yMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y ); cbox->yMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y ); } else if ( mode == FT_RENDER_MODE_LCD_V ) { cbox->xMin -= FT_MAX( FT_MAX( sub[0].y, sub[1].y ), sub[2].y ); cbox->xMax -= FT_MIN( FT_MIN( sub[0].y, sub[1].y ), sub[2].y ); cbox->yMin += FT_MIN( FT_MIN( sub[0].x, sub[1].x ), sub[2].x ); cbox->yMax += FT_MAX( FT_MAX( sub[0].x, sub[1].x ), sub[2].x ); } }
ssize_t handle_wstr(char **format, va_list *args, t_arg *arg) { wchar_t *str; size_t strlen; (void)format; (void)arg; str = va_arg(*args, wchar_t*); if (str == NULL) str = L"(null)"; strlen = arg->got_precision ? calc_wstrlen(str, arg->precision, 0) : ft_wstrlen(str); if (arg->got_width && !arg->right_pad) width_pad(strlen, arg->width, arg->pad_zeroes ? '0' : ' '); ft_putnwstr(str, strlen); if (arg->got_width && arg->right_pad) width_pad(strlen, arg->width, ' '); return (arg->got_width ? FT_MAX(strlen, arg->width) : strlen); }
int main(int ac, char **av) { t_fdf e; fdf_ini(&e); if (ac < 2 || !my_parse(&e, ac, av)) return (0); e.wia = FT_MAX(e.maa - e.mia, 1); if (!(e.mlx = mlx_init())) return (fdf_quit(&e)); if (!(e.win = mlx_new_window(e.mlx, e.wid, e.hig, "FdF"))) return (fdf_quit(&e)); if (!(e.img = mlx_new_image(e.mlx, e.wid, e.hig))) return (fdf_quit(&e)); e.buf = mlx_get_data_addr(e.img, &e.bit, &e.lin, &e.end); e.bit /= 8; prepare_image(&e); mlx_key_hook(e.win, &my_key_func, &e); mlx_expose_hook(e.win, &my_expose_func, &e); mlx_loop(e.mlx); return (0); }
ssize_t handle_str(char **format, va_list *args, t_arg *arg) { char *str; size_t strlen; if (arg->length == l) return (handle_wstr(format, args, arg)); else { str = va_arg(*args, char*); if (str == NULL) str = "(null)"; strlen = arg->got_precision ? ft_nstrlen(str, arg->precision) : ft_strlen(str); if (arg->got_width && !arg->right_pad) width_pad(strlen, arg->width, arg->pad_zeroes ? '0' : ' '); ft_putnstr(str, strlen); if (arg->got_width && arg->right_pad) width_pad(strlen, arg->width, ' '); return (arg->got_width ? FT_MAX(strlen, arg->width) : strlen); } }
static FT_Error load_format_20( TT_Face face, FT_Stream stream, FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; FT_Int num_glyphs; FT_UShort num_names; FT_UShort* glyph_indices = NULL; FT_Char** name_strings = NULL; if ( FT_READ_USHORT( num_glyphs ) ) goto Exit; /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ /* than the value in the maxp table (cf. cyberbit.ttf). */ /* There already exist fonts which have more than 32768 glyph names */ /* in this table, so the test for this threshold has been dropped. */ if ( num_glyphs > face->max_profile.numGlyphs ) { error = FT_THROW( Invalid_File_Format ); goto Exit; } /* load the indices */ { FT_Int n; if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || FT_FRAME_ENTER( num_glyphs * 2L ) ) goto Fail; for ( n = 0; n < num_glyphs; n++ ) glyph_indices[n] = FT_GET_USHORT(); FT_FRAME_EXIT(); } /* compute number of names stored in table */ { FT_Int n; num_names = 0; for ( n = 0; n < num_glyphs; n++ ) { FT_Int idx; idx = glyph_indices[n]; if ( idx >= 258 ) { idx -= 257; if ( idx > num_names ) num_names = (FT_UShort)idx; } } } /* now load the name strings */ { FT_UShort n; if ( FT_NEW_ARRAY( name_strings, num_names ) ) goto Fail; for ( n = 0; n < num_names; n++ ) { FT_UInt len; if ( FT_STREAM_POS() >= post_limit ) break; else { FT_TRACE6(( "load_format_20: %d byte left in post table\n", post_limit - FT_STREAM_POS() )); if ( FT_READ_BYTE( len ) ) goto Fail1; } if ( len > post_limit || FT_STREAM_POS() > post_limit - len ) { FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS(); FT_ERROR(( "load_format_20:" " exceeding string length (%d)," " truncating at end of post table (%d byte left)\n", len, d )); len = (FT_UInt)FT_MAX( 0, d ); } if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || FT_STREAM_READ( name_strings[n], len ) ) goto Fail1; name_strings[n][len] = '\0'; } if ( n < num_names ) { FT_ERROR(( "load_format_20:" " all entries in post table are already parsed," " using NULL names for gid %d - %d\n", n, num_names - 1 )); for ( ; n < num_names; n++ ) if ( FT_NEW_ARRAY( name_strings[n], 1 ) ) goto Fail1; else name_strings[n][0] = '\0'; } } /* all right, set table fields and exit successfully */ { TT_Post_20 table = &face->postscript_names.names.format_20; table->num_glyphs = (FT_UShort)num_glyphs; table->num_names = (FT_UShort)num_names; table->glyph_indices = glyph_indices; table->glyph_names = name_strings; } return FT_Err_Ok; Fail1: { FT_UShort n; for ( n = 0; n < num_names; n++ ) FT_FREE( name_strings[n] ); } Fail: FT_FREE( name_strings ); FT_FREE( glyph_indices ); Exit: return error; }
af_loader_compute_darkening( AF_Loader loader, FT_Face face, FT_Pos standard_width ) { AF_Module module = loader->globals->module; FT_UShort units_per_EM; FT_Fixed ppem, em_ratio; FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount; FT_Int log_base_2; FT_Int x1, y1, x2, y2, x3, y3, x4, y4; ppem = FT_MAX( af_intToFixed( 4 ), af_intToFixed( face->size->metrics.x_ppem ) ); units_per_EM = face->units_per_EM; em_ratio = FT_DivFix( af_intToFixed( 1000 ), af_intToFixed ( units_per_EM ) ); if ( em_ratio < af_floatToFixed( .01 ) ) { /* If something goes wrong, don't embolden. */ return 0; } x1 = module->darken_params[0]; y1 = module->darken_params[1]; x2 = module->darken_params[2]; y2 = module->darken_params[3]; x3 = module->darken_params[4]; y3 = module->darken_params[5]; x4 = module->darken_params[6]; y4 = module->darken_params[7]; if ( standard_width <= 0 ) { stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */ stem_width_per_1000 = stem_width; } else { stem_width = af_intToFixed( standard_width ); stem_width_per_1000 = FT_MulFix( stem_width, em_ratio ); } log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) + FT_MSB( (FT_UInt32)ppem ); if ( log_base_2 >= 46 ) { /* possible overflow */ scaled_stem = af_intToFixed( x4 ); } else scaled_stem = FT_MulFix( stem_width_per_1000, ppem ); /* now apply the darkening parameters */ if ( scaled_stem < af_intToFixed( x1 ) ) darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem ); else if ( scaled_stem < af_intToFixed( x2 ) ) { FT_Int xdelta = x2 - x1; FT_Int ydelta = y2 - y1; FT_Int x = stem_width_per_1000 - FT_DivFix( af_intToFixed( x1 ), ppem ); if ( !xdelta ) goto Try_x3; darken_amount = FT_MulDiv( x, ydelta, xdelta ) + FT_DivFix( af_intToFixed( y1 ), ppem ); } else if ( scaled_stem < af_intToFixed( x3 ) ) { Try_x3: { FT_Int xdelta = x3 - x2; FT_Int ydelta = y3 - y2; FT_Int x = stem_width_per_1000 - FT_DivFix( af_intToFixed( x2 ), ppem ); if ( !xdelta ) goto Try_x4; darken_amount = FT_MulDiv( x, ydelta, xdelta ) + FT_DivFix( af_intToFixed( y2 ), ppem ); } } else if ( scaled_stem < af_intToFixed( x4 ) ) { Try_x4: { FT_Int xdelta = x4 - x3; FT_Int ydelta = y4 - y3; FT_Int x = stem_width_per_1000 - FT_DivFix( af_intToFixed( x3 ), ppem ); if ( !xdelta ) goto Use_y4; darken_amount = FT_MulDiv( x, ydelta, xdelta ) + FT_DivFix( af_intToFixed( y3 ), ppem ); } } else { Use_y4: darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem ); } /* Convert darken_amount from per 1000 em to true character space. */ return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); }
cf2_blues_capture( const CF2_Blues blues, CF2_Hint bottomHintEdge, CF2_Hint topHintEdge ) { /* TODO: validate? */ CF2_Fixed csFuzz = blues->blueFuzz; /* new position of captured edge */ CF2_Fixed dsNew; /* amount that hint is moved when positioned */ CF2_Fixed dsMove = 0; FT_Bool captured = FALSE; CF2_UInt i; /* assert edge flags are consistent */ FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) && !cf2_hint_isBottom( topHintEdge ) ); /* TODO: search once without blue fuzz for compatibility with coretype? */ for ( i = 0; i < blues->count; i++ ) { if ( blues->zone[i].bottomZone && cf2_hint_isBottom( bottomHintEdge ) ) { if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= bottomHintEdge->csCoord && bottomHintEdge->csCoord <= ( blues->zone[i].csTopEdge + csFuzz ) ) { /* bottom edge captured by bottom zone */ if ( blues->suppressOvershoot ) dsNew = blues->zone[i].dsFlatEdge; else if ( ( blues->zone[i].csTopEdge - bottomHintEdge->csCoord ) >= blues->blueShift ) { /* guarantee minimum of 1 pixel overshoot */ dsNew = FT_MIN( cf2_fixedRound( bottomHintEdge->dsCoord ), blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) ); } else { /* simply round captured edge */ dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); } dsMove = dsNew - bottomHintEdge->dsCoord; captured = TRUE; break; } } if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) { if ( ( blues->zone[i].csBottomEdge - csFuzz ) <= topHintEdge->csCoord && topHintEdge->csCoord <= ( blues->zone[i].csTopEdge + csFuzz ) ) { /* top edge captured by top zone */ if ( blues->suppressOvershoot ) dsNew = blues->zone[i].dsFlatEdge; else if ( ( topHintEdge->csCoord - blues->zone[i].csBottomEdge ) >= blues->blueShift ) { /* guarantee minimum of 1 pixel overshoot */ dsNew = FT_MAX( cf2_fixedRound( topHintEdge->dsCoord ), blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) ); } else { /* simply round captured edge */ dsNew = cf2_fixedRound( topHintEdge->dsCoord ); } dsMove = dsNew - topHintEdge->dsCoord; captured = TRUE; break; } } } if ( captured ) { /* move both edges and flag them `locked' */ if ( cf2_hint_isValid( bottomHintEdge ) ) { bottomHintEdge->dsCoord += dsMove; cf2_hint_lock( bottomHintEdge ); } if ( cf2_hint_isValid( topHintEdge ) ) { topHintEdge->dsCoord += dsMove; cf2_hint_lock( topHintEdge ); } } return captured; }
FT_Outline_Get_Orientation( FT_Outline* outline ) { FT_BBox cbox; FT_Int xshift, yshift; FT_Vector* points; FT_Vector v_prev, v_cur; FT_Int c, n, first; FT_Pos area = 0; if ( !outline || outline->n_points <= 0 ) return FT_ORIENTATION_TRUETYPE; /* We use the nonzero winding rule to find the orientation. */ /* Since glyph outlines behave much more `regular' than arbitrary */ /* cubic or quadratic curves, this test deals with the polygon */ /* only that is spanned up by the control points. */ FT_Outline_Get_CBox( outline, &cbox ); /* Handle collapsed outlines to avoid undefined FT_MSB. */ if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax ) return FT_ORIENTATION_NONE; xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) ) - 14; xshift = FT_MAX( xshift, 0 ); yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14; yshift = FT_MAX( yshift, 0 ); points = outline->points; first = 0; for ( c = 0; c < outline->n_contours; c++ ) { FT_Int last = outline->contours[c]; v_prev.x = points[last].x >> xshift; v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { v_cur.x = points[n].x >> xshift; v_cur.y = points[n].y >> yshift; area = ADD_LONG( area, ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) ); v_prev = v_cur; } first = last + 1; } if ( area > 0 ) return FT_ORIENTATION_POSTSCRIPT; else if ( area < 0 ) return FT_ORIENTATION_TRUETYPE; else return FT_ORIENTATION_NONE; }
/* caller's transform is adjusted for subpixel positioning */ static void cf2_font_setup( CF2_Font font, const CF2_Matrix* transform ) { /* pointer to parsed font object */ CFF_Decoder* decoder = font->decoder; FT_Bool needExtraSetup = FALSE; /* character space units */ CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; CF2_Fixed ppem; /* clear previous error */ font->error = FT_Err_Ok; /* if a CID fontDict has changed, we need to recompute some cached */ /* data */ needExtraSetup = font->lastSubfont != cf2_getSubfont( decoder ); /* if ppem has changed, we need to recompute some cached data */ /* note: because of CID font matrix concatenation, ppem and transform */ /* do not necessarily track. */ ppem = cf2_getPpemY( decoder ); if ( font->ppem != ppem ) { font->ppem = ppem; needExtraSetup = TRUE; } /* copy hinted flag on each call */ font->hinted = font->renderingFlags & CF2_FlagsHinted; /* determine if transform has changed; */ /* include Fontmatrix but ignore translation */ if ( ft_memcmp( transform, &font->currentTransform, 4 * sizeof ( CF2_Fixed ) ) != 0 ) { /* save `key' information for `cache of one' matrix data; */ /* save client transform, without the translation */ font->currentTransform = *transform; font->currentTransform.tx = font->currentTransform.ty = cf2_intToFixed( 0 ); /* TODO: FreeType transform is simple scalar; for now, use identity */ /* for outer */ font->innerTransform = *transform; font->outerTransform.a = font->outerTransform.d = cf2_intToFixed( 1 ); font->outerTransform.b = font->outerTransform.c = cf2_intToFixed( 0 ); needExtraSetup = TRUE; } /* * font->darkened is set to true if there is a stem darkening request or * the font is synthetic emboldened. * font->darkened controls whether to adjust blue zones, winding order, * and hinting. * */ if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) ) { font->stemDarkened = font->renderingFlags & CF2_FlagsDarkened; /* blue zones depend on darkened flag */ needExtraSetup = TRUE; } /* recompute variables that are dependent on transform or FontDict or */ /* darken flag */ if ( needExtraSetup ) { /* StdVW is found in the private dictionary; */ /* recompute darkening amounts whenever private dictionary or */ /* transform change */ /* Note: a rendering flag turns darkening on or off, so we want to */ /* store the `on' amounts; */ /* darkening amount is computed in character space */ /* TODO: testing size-dependent darkening here; */ /* what to do for rotations? */ CF2_Fixed emRatio; CF2_Fixed stdHW; CF2_Int unitsPerEm = font->unitsPerEm; if ( unitsPerEm == 0 ) unitsPerEm = 1000; ppem = FT_MAX( cf2_intToFixed( 4 ), font->ppem ); /* use minimum ppem of 4 */ #if 0 /* since vstem is measured in the x-direction, we use the `a' member */ /* of the fontMatrix */ emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a ); #endif /* Freetype does not preserve the fontMatrix when parsing; use */ /* unitsPerEm instead. */ /* TODO: check precision of this */ emRatio = cf2_intToFixed( 1000 ) / unitsPerEm; font->stdVW = cf2_getStdVW( decoder ); if ( font->stdVW <= 0 ) font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); if ( boldenX > 0 ) { /* Ensure that boldenX is at least 1 pixel for synthetic bold font */ /* (similar to what Avalon does) */ boldenX = FT_MAX( boldenX, FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) ); /* Synthetic emboldening adds at least 1 pixel to darkenX, while */ /* stem darkening adds at most half pixel. Since the purpose of */ /* stem darkening (readability at small sizes) is met with */ /* synthetic emboldening, no need to add stem darkening for a */ /* synthetic bold font. */ cf2_computeDarkening( emRatio, ppem, font->stdVW, &font->darkenX, boldenX, FALSE ); } else cf2_computeDarkening( emRatio, ppem, font->stdVW, &font->darkenX, 0, font->stemDarkened ); #if 0 /* since hstem is measured in the y-direction, we use the `d' member */ /* of the fontMatrix */ /* TODO: use the same units per em as above; check this */ emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d ); #endif /* set the default stem width, because it must be the same for all */ /* family members; */ /* choose a constant for StdHW that depends on font contrast */ stdHW = cf2_getStdHW( decoder ); if ( stdHW > 0 && font->stdVW > 2 * stdHW ) font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); else { /* low contrast font gets less hstem darkening */ font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio ); } cf2_computeDarkening( emRatio, ppem, font->stdHW, &font->darkenY, boldenY, font->stemDarkened ); if ( font->darkenX != 0 || font->darkenY != 0 ) font->darkened = TRUE; else font->darkened = FALSE; font->reverseWinding = FALSE; /* initial expectation is CCW */ /* compute blue zones for this instance */ cf2_blues_init( &font->blues, font ); } }
void CPageMgr::InsertPageInfo(void * addr, size_t pagecount, bool frommmap) { struct SPageInfo * pageInfo = AllocPageInfo(); RB_NODE_INIT(pageInfo->address_node); RB_NODE_INIT(pageInfo->free_node); pageInfo->base_address = (size_t)addr; pageInfo->page_count = pagecount; if (frommmap) { pageInfo->UnSetFlag(SPageInfo::E_MEM_SOURCE_OFF); } else { pageInfo->SetFlag(SPageInfo::E_MEM_SOURCE_OFF); } PRINT("addr:%p, pages:%zd, mmap:%d", addr, pagecount, frommmap); PRINT("mgr info, address tree size:%zd", m_iAddressTreeSize); if (m_iAddressTreeSize == 0) { InsertPageInfo(pageInfo); m_iMaxContinuePages = pageInfo->page_count; m_iAddressTreeSize ++; } else if (m_iAddressTreeSize == 1) { rb_node * node = rb_first(&m_cAddressTree); struct SPageInfo * pInfo = (struct SPageInfo *)AddressTreeGetObject(node); if (pInfo->flag == pageInfo->flag && (pInfo->BeginAddress() == pageInfo->EndAddress() || pageInfo->BeginAddress() == pInfo->EndAddress())) { RemoveFreeTree(pInfo); RemoveCountTreeIfNeed(pInfo->page_count); RemoveIndexTreeIfNeed(pInfo->page_count); pInfo->base_address = FT_MIN(pInfo->base_address, pInfo->base_address); pInfo->page_count += pageInfo->page_count; InsertIndexTreeIfNeed(pInfo->page_count); InsertCountTreeIfNeed(pInfo->page_count); InsertFreeTree(pInfo); ReleasePageInfo(pageInfo); m_iMaxContinuePages = pInfo->page_count; } else { InsertPageInfo(pageInfo); m_iMaxContinuePages = FT_MAX(pageInfo->page_count, pInfo->page_count); m_iAddressTreeSize ++; } } else { struct SPageInfo * prevInfo = GetPageInfoByAddress(pageInfo->BeginAddress() - 1); struct SPageInfo * nextInfo = GetPageInfoByAddress(pageInfo->EndAddress()); if (prevInfo != NULL && prevInfo->flag == pageInfo->flag) { pageInfo->base_address = prevInfo->base_address; pageInfo->page_count += prevInfo->page_count; RemovePageInfo(prevInfo); m_iAddressTreeSize --; prevInfo = NULL; } if (nextInfo != NULL && nextInfo->flag == pageInfo->flag) { pageInfo->page_count += nextInfo->page_count; RemovePageInfo(nextInfo); m_iAddressTreeSize --; nextInfo = NULL; } InsertPageInfo(pageInfo); m_iMaxContinuePages = FT_MAX(pageInfo->page_count, m_iMaxContinuePages); m_iAddressTreeSize ++; } m_iFreePages += pagecount; }
tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index, FT_GlyphSlot dstSlot, FT_GlyphSlot srcSlot ) { FT_Error error; FT_UInt x, y; FT_Byte b, g, r, alpha; FT_ULong size; FT_Byte* src; FT_Byte* dst; if ( !dstSlot->bitmap.buffer ) { /* Initialize destination of color bitmap */ /* with the size of first component. */ dstSlot->bitmap_left = srcSlot->bitmap_left; dstSlot->bitmap_top = srcSlot->bitmap_top; dstSlot->bitmap.width = srcSlot->bitmap.width; dstSlot->bitmap.rows = srcSlot->bitmap.rows; dstSlot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA; dstSlot->bitmap.pitch = (int)dstSlot->bitmap.width * 4; dstSlot->bitmap.num_grays = 256; size = dstSlot->bitmap.rows * (unsigned int)dstSlot->bitmap.pitch; error = ft_glyphslot_alloc_bitmap( dstSlot, size ); if ( error ) return error; FT_MEM_ZERO( dstSlot->bitmap.buffer, size ); } else { /* Resize destination if needed such that new component fits. */ FT_Int x_min, x_max, y_min, y_max; x_min = FT_MIN( dstSlot->bitmap_left, srcSlot->bitmap_left ); x_max = FT_MAX( dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width, srcSlot->bitmap_left + (FT_Int)srcSlot->bitmap.width ); y_min = FT_MIN( dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows, srcSlot->bitmap_top - (FT_Int)srcSlot->bitmap.rows ); y_max = FT_MAX( dstSlot->bitmap_top, srcSlot->bitmap_top ); if ( x_min != dstSlot->bitmap_left || x_max != dstSlot->bitmap_left + (FT_Int)dstSlot->bitmap.width || y_min != dstSlot->bitmap_top - (FT_Int)dstSlot->bitmap.rows || y_max != dstSlot->bitmap_top ) { FT_Memory memory = face->root.memory; FT_UInt width = (FT_UInt)( x_max - x_min ); FT_UInt rows = (FT_UInt)( y_max - y_min ); FT_UInt pitch = width * 4; FT_Byte* buf = NULL; FT_Byte* p; FT_Byte* q; size = rows * pitch; if ( FT_ALLOC( buf, size ) ) return error; p = dstSlot->bitmap.buffer; q = buf + (int)pitch * ( y_max - dstSlot->bitmap_top ) + 4 * ( dstSlot->bitmap_left - x_min ); for ( y = 0; y < dstSlot->bitmap.rows; y++ ) { FT_MEM_COPY( q, p, dstSlot->bitmap.width * 4 ); p += dstSlot->bitmap.pitch; q += pitch; } ft_glyphslot_set_bitmap( dstSlot, buf ); dstSlot->bitmap_top = y_max; dstSlot->bitmap_left = x_min; dstSlot->bitmap.width = width; dstSlot->bitmap.rows = rows; dstSlot->bitmap.pitch = (int)pitch; dstSlot->internal->flags |= FT_GLYPH_OWN_BITMAP; dstSlot->format = FT_GLYPH_FORMAT_BITMAP; } } if ( color_index == 0xFFFF ) { if ( face->have_foreground_color ) { b = face->foreground_color.blue; g = face->foreground_color.green; r = face->foreground_color.red; alpha = face->foreground_color.alpha; } else { if ( face->palette_data.palette_flags && ( face->palette_data.palette_flags[face->palette_index] & FT_PALETTE_FOR_DARK_BACKGROUND ) ) { /* white opaque */ b = 0xFF; g = 0xFF; r = 0xFF; alpha = 0xFF; } else { /* black opaque */ b = 0x00; g = 0x00; r = 0x00; alpha = 0xFF; } } } else { b = face->palette[color_index].blue; g = face->palette[color_index].green; r = face->palette[color_index].red; alpha = face->palette[color_index].alpha; } /* XXX Convert if srcSlot.bitmap is not grey? */ src = srcSlot->bitmap.buffer; dst = dstSlot->bitmap.buffer + dstSlot->bitmap.pitch * ( dstSlot->bitmap_top - srcSlot->bitmap_top ) + 4 * ( srcSlot->bitmap_left - dstSlot->bitmap_left ); for ( y = 0; y < srcSlot->bitmap.rows; y++ ) { for ( x = 0; x < srcSlot->bitmap.width; x++ ) { int aa = src[x]; int fa = alpha * aa / 255; int fb = b * fa / 255; int fg = g * fa / 255; int fr = r * fa / 255; int ba2 = 255 - fa; int bb = dst[4 * x + 0]; int bg = dst[4 * x + 1]; int br = dst[4 * x + 2]; int ba = dst[4 * x + 3]; dst[4 * x + 0] = (FT_Byte)( bb * ba2 / 255 + fb ); dst[4 * x + 1] = (FT_Byte)( bg * ba2 / 255 + fg ); dst[4 * x + 2] = (FT_Byte)( br * ba2 / 255 + fr ); dst[4 * x + 3] = (FT_Byte)( ba * ba2 / 255 + fa ); } src += srcSlot->bitmap.pitch; dst += dstSlot->bitmap.pitch; } return FT_Err_Ok; }