|
@@ -845,7 +845,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
|
|
|
|
|
|
if (ret.index == -1) {
|
|
|
// Could not find texture to fit, create one.
|
|
|
- int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256);
|
|
|
+ int texsize = MAX(p_data->size.x * 0.125, 256);
|
|
|
|
|
|
texsize = next_power_of_2(texsize);
|
|
|
if (p_msdf) {
|
|
@@ -1079,7 +1079,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
|
|
|
#ifdef MODULE_FREETYPE_ENABLED
|
|
|
_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap p_bitmap, int p_yofs, int p_xofs, const Vector2 &p_advance, bool p_bgra) const {
|
|
|
FontGlyph chr;
|
|
|
- chr.advance = p_advance * p_data->scale / p_data->oversampling;
|
|
|
+ chr.advance = p_advance * p_data->scale;
|
|
|
chr.found = true;
|
|
|
|
|
|
int w = p_bitmap.width;
|
|
@@ -1192,8 +1192,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
|
|
|
chr.texture_idx = tex_pos.index;
|
|
|
|
|
|
chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2);
|
|
|
- chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale / p_data->oversampling;
|
|
|
- chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling;
|
|
|
+ chr.rect.position = Vector2(p_xofs - p_rect_margin, -p_yofs - p_rect_margin) * p_data->scale;
|
|
|
+ chr.rect.size = chr.uv_rect.size * p_data->scale;
|
|
|
return chr;
|
|
|
}
|
|
|
#endif
|
|
@@ -1202,9 +1202,9 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
|
|
|
/* Font Cache */
|
|
|
/*************************************************************************/
|
|
|
|
|
|
-_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph) const {
|
|
|
+_FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph, FontGlyph &r_glyph, uint32_t p_oversampling) const {
|
|
|
FontForSizeAdvanced *fd = nullptr;
|
|
|
- ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd), false);
|
|
|
+ ERR_FAIL_COND_V(!_ensure_cache_for_size(p_font_data, p_size, fd, false, p_oversampling), false);
|
|
|
|
|
|
int32_t glyph_index = p_glyph & 0xffffff; // Remove subpixel shifts.
|
|
|
|
|
@@ -1258,17 +1258,17 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
|
|
|
}
|
|
|
|
|
|
if (!p_font_data->msdf) {
|
|
|
- if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 4;
|
|
|
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
|
|
|
- } else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (p_font_data->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && p_size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
FT_Pos xshift = (int)((p_glyph >> 27) & 3) << 5;
|
|
|
FT_Outline_Translate(&fd->face->glyph->outline, xshift, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (p_font_data->embolden != 0.f) {
|
|
|
- FT_Pos strength = p_font_data->embolden * p_size.x * fd->oversampling * 4; // 26.6 fractional units (1 / 64).
|
|
|
+ FT_Pos strength = p_font_data->embolden * p_size.x / 16; // 26.6 fractional units (1 / 64).
|
|
|
FT_Outline_Embolden(&fd->face->glyph->outline, strength);
|
|
|
}
|
|
|
|
|
@@ -1337,7 +1337,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
|
|
|
ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph stroker.");
|
|
|
}
|
|
|
|
|
|
- FT_Stroker_Set(stroker, (int)(fd->size.y * fd->oversampling * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
|
|
|
+ FT_Stroker_Set(stroker, (int)(fd->size.y * 16.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
|
|
|
FT_Glyph glyph;
|
|
|
FT_BitmapGlyph glyph_bitmap;
|
|
|
|
|
@@ -1369,12 +1369,19 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent) const {
|
|
|
+_FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size, FontForSizeAdvanced *&r_cache_for_size, bool p_silent, uint32_t p_oversampling) const {
|
|
|
ERR_FAIL_COND_V(p_size.x <= 0, false);
|
|
|
|
|
|
HashMap<Vector2i, FontForSizeAdvanced *>::Iterator E = p_font_data->cache.find(p_size);
|
|
|
if (E) {
|
|
|
r_cache_for_size = E->value;
|
|
|
+ // Size used directly, remove from oversampling list.
|
|
|
+ if (p_oversampling == 0 && E->value->viewport_oversampling != 0) {
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(E->value->viewport_oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->fonts.erase(E->value);
|
|
|
+ }
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1428,41 +1435,44 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ double sz = double(fd->size.x) / 64.0;
|
|
|
if (p_font_data->msdf) {
|
|
|
- fd->oversampling = 1.0;
|
|
|
- fd->size.x = p_font_data->msdf_source_size;
|
|
|
- } else if (p_font_data->oversampling <= 0.0) {
|
|
|
- fd->oversampling = _font_get_global_oversampling();
|
|
|
- } else {
|
|
|
- fd->oversampling = p_font_data->oversampling;
|
|
|
+ sz = p_font_data->msdf_source_size;
|
|
|
}
|
|
|
|
|
|
if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) {
|
|
|
int best_match = 0;
|
|
|
- int diff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[0].width));
|
|
|
- fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width;
|
|
|
+ int diff = Math::abs(sz - ((int64_t)fd->face->available_sizes[0].width));
|
|
|
+ fd->scale = sz / fd->face->available_sizes[0].width;
|
|
|
for (int i = 1; i < fd->face->num_fixed_sizes; i++) {
|
|
|
- int ndiff = Math::abs(fd->size.x - ((int64_t)fd->face->available_sizes[i].width));
|
|
|
+ int ndiff = Math::abs(sz - ((int64_t)fd->face->available_sizes[i].width));
|
|
|
if (ndiff < diff) {
|
|
|
best_match = i;
|
|
|
diff = ndiff;
|
|
|
- fd->scale = double(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width;
|
|
|
+ fd->scale = sz / fd->face->available_sizes[i].width;
|
|
|
}
|
|
|
}
|
|
|
FT_Select_Size(fd->face, best_match);
|
|
|
} else {
|
|
|
- FT_Set_Pixel_Sizes(fd->face, 0, double(fd->size.x * fd->oversampling));
|
|
|
+ FT_Size_RequestRec req;
|
|
|
+ req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
|
|
|
+ req.width = sz * 64.0;
|
|
|
+ req.height = sz * 64.0;
|
|
|
+ req.horiResolution = 0;
|
|
|
+ req.vertResolution = 0;
|
|
|
+
|
|
|
+ FT_Request_Size(fd->face, &req);
|
|
|
if (fd->face->size->metrics.y_ppem != 0) {
|
|
|
- fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem;
|
|
|
+ fd->scale = sz / (double)fd->face->size->metrics.y_ppem;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
fd->hb_handle = hb_ft_font_create(fd->face, nullptr);
|
|
|
|
|
|
- fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale;
|
|
|
- fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->oversampling * fd->scale;
|
|
|
- fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
|
|
|
- fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale;
|
|
|
+ fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->scale;
|
|
|
+ fd->descent = (-fd->face->size->metrics.descender / 64.0) / fd->scale;
|
|
|
+ fd->underline_position = (-FT_MulFix(fd->face->underline_position, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
|
|
|
+ fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->scale;
|
|
|
|
|
|
#if HB_VERSION_ATLEAST(3, 3, 0)
|
|
|
hb_font_set_synthetic_slant(fd->hb_handle, p_font_data->transform[0][1]);
|
|
@@ -1869,11 +1879,53 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
|
|
|
// Init bitmap font.
|
|
|
fd->hb_handle = _bmp_font_create(fd, nullptr);
|
|
|
}
|
|
|
+
|
|
|
+ fd->owner = p_font_data;
|
|
|
p_font_data->cache.insert(p_size, fd);
|
|
|
r_cache_for_size = fd;
|
|
|
+ if (p_oversampling != 0) {
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(p_oversampling);
|
|
|
+ if (ol) {
|
|
|
+ fd->viewport_oversampling = p_oversampling;
|
|
|
+ ol->fonts.insert(fd);
|
|
|
+ }
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+void TextServerAdvanced::_reference_oversampling_level(double p_oversampling) {
|
|
|
+ uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
|
|
|
+ if (oversampling == 64) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->refcount++;
|
|
|
+ } else {
|
|
|
+ OversamplingLevel new_ol;
|
|
|
+ oversampling_levels.insert(oversampling, new_ol);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void TextServerAdvanced::_unreference_oversampling_level(double p_oversampling) {
|
|
|
+ uint32_t oversampling = CLAMP(p_oversampling, 0.1, 100.0) * 64;
|
|
|
+ if (oversampling == 64) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->refcount--;
|
|
|
+ if (ol->refcount == 0) {
|
|
|
+ for (FontForSizeAdvanced *fd : ol->fonts) {
|
|
|
+ fd->owner->cache.erase(fd->size);
|
|
|
+ memdelete(fd);
|
|
|
+ }
|
|
|
+ ol->fonts.clear();
|
|
|
+ oversampling_levels.erase(oversampling);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
_FORCE_INLINE_ bool TextServerAdvanced::_font_validate(const RID &p_font_rid) const {
|
|
|
FontAdvanced *fd = _get_font_data(p_font_rid);
|
|
|
ERR_FAIL_NULL_V(fd, false);
|
|
@@ -1888,6 +1940,12 @@ _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontAdvanced *p_font_d
|
|
|
MutexLock ftlock(ft_mutex);
|
|
|
|
|
|
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : p_font_data->cache) {
|
|
|
+ if (E.value->viewport_oversampling != 0) {
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->fonts.erase(E.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
memdelete(E.value);
|
|
|
}
|
|
|
p_font_data->cache.clear();
|
|
@@ -2623,34 +2681,42 @@ Dictionary TextServerAdvanced::_font_get_variation_coordinates(const RID &p_font
|
|
|
return fd->variation_coordinates;
|
|
|
}
|
|
|
|
|
|
-void TextServerAdvanced::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
|
|
|
+TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_font_rid) const {
|
|
|
FontAdvanced *fd = _get_font_data(p_font_rid);
|
|
|
- ERR_FAIL_NULL(fd);
|
|
|
+ ERR_FAIL_NULL_V(fd, TypedArray<Vector2i>());
|
|
|
|
|
|
MutexLock lock(fd->mutex);
|
|
|
- if (fd->oversampling != p_oversampling) {
|
|
|
- _font_clear_cache(fd);
|
|
|
- fd->oversampling = p_oversampling;
|
|
|
+ TypedArray<Vector2i> ret;
|
|
|
+ for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
|
|
|
+ if ((E.key.x % 64 == 0) && (E.value->viewport_oversampling == 0)) {
|
|
|
+ ret.push_back(Vector2i(E.key.x / 64, E.key.y));
|
|
|
+ }
|
|
|
}
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
-double TextServerAdvanced::_font_get_oversampling(const RID &p_font_rid) const {
|
|
|
- FontAdvanced *fd = _get_font_data(p_font_rid);
|
|
|
- ERR_FAIL_NULL_V(fd, 0.0);
|
|
|
-
|
|
|
- MutexLock lock(fd->mutex);
|
|
|
- return fd->oversampling;
|
|
|
-}
|
|
|
-
|
|
|
-TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_font_rid) const {
|
|
|
+TypedArray<Dictionary> TextServerAdvanced::_font_get_size_cache_info(const RID &p_font_rid) const {
|
|
|
FontAdvanced *fd = _get_font_data(p_font_rid);
|
|
|
- ERR_FAIL_NULL_V(fd, TypedArray<Vector2i>());
|
|
|
+ ERR_FAIL_NULL_V(fd, TypedArray<Dictionary>());
|
|
|
|
|
|
MutexLock lock(fd->mutex);
|
|
|
- TypedArray<Vector2i> ret;
|
|
|
+ TypedArray<Dictionary> ret;
|
|
|
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
|
|
|
- ret.push_back(E.key);
|
|
|
+ Dictionary size_info;
|
|
|
+ size_info["size_px"] = Vector2i(E.key.x / 64, E.key.y);
|
|
|
+ if (E.value->viewport_oversampling) {
|
|
|
+ size_info["viewport_oversampling"] = double(E.value->viewport_oversampling) / 64.0;
|
|
|
+ }
|
|
|
+ size_info["glyphs"] = E.value->glyph_map.size();
|
|
|
+ size_info["textures"] = E.value->textures.size();
|
|
|
+ uint64_t sz = 0;
|
|
|
+ for (const ShelfPackTexture &tx : E.value->textures) {
|
|
|
+ sz += tx.image->get_data_size() * 2;
|
|
|
+ }
|
|
|
+ size_info["textures_size"] = sz;
|
|
|
+ ret.push_back(size_info);
|
|
|
}
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -2661,6 +2727,12 @@ void TextServerAdvanced::_font_clear_size_cache(const RID &p_font_rid) {
|
|
|
MutexLock lock(fd->mutex);
|
|
|
MutexLock ftlock(ft_mutex);
|
|
|
for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
|
|
|
+ if (E.value->viewport_oversampling != 0) {
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(E.value->viewport_oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->fonts.erase(E.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
memdelete(E.value);
|
|
|
}
|
|
|
fd->cache.clear();
|
|
@@ -2672,9 +2744,16 @@ void TextServerAdvanced::_font_remove_size_cache(const RID &p_font_rid, const Ve
|
|
|
|
|
|
MutexLock lock(fd->mutex);
|
|
|
MutexLock ftlock(ft_mutex);
|
|
|
- if (fd->cache.has(p_size)) {
|
|
|
- memdelete(fd->cache[p_size]);
|
|
|
- fd->cache.erase(p_size);
|
|
|
+ Vector2i size = Vector2i(p_size.x * 64, p_size.y);
|
|
|
+ if (fd->cache.has(size)) {
|
|
|
+ if (fd->cache[size]->viewport_oversampling != 0) {
|
|
|
+ OversamplingLevel *ol = oversampling_levels.getptr(fd->cache[size]->viewport_oversampling);
|
|
|
+ if (ol) {
|
|
|
+ ol->fonts.erase(fd->cache[size]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ memdelete(fd->cache[size]);
|
|
|
+ fd->cache.erase(size);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2702,7 +2781,7 @@ double TextServerAdvanced::_font_get_ascent(const RID &p_font_rid, int64_t p_siz
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return ffsd->ascent * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return ffsd->ascent * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -2736,7 +2815,7 @@ double TextServerAdvanced::_font_get_descent(const RID &p_font_rid, int64_t p_si
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return ffsd->descent * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return ffsd->descent * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -2771,7 +2850,7 @@ double TextServerAdvanced::_font_get_underline_position(const RID &p_font_rid, i
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return ffsd->underline_position * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return ffsd->underline_position * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -2806,7 +2885,7 @@ double TextServerAdvanced::_font_get_underline_thickness(const RID &p_font_rid,
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return ffsd->underline_thickness * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return ffsd->underline_thickness * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -2847,14 +2926,14 @@ double TextServerAdvanced::_font_get_scale(const RID &p_font_rid, int64_t p_size
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return ffsd->scale * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return ffsd->scale * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
|
return ffsd->scale * Math::round((double)p_size / (double)fd->fixed_size);
|
|
|
}
|
|
|
} else {
|
|
|
- return ffsd->scale / ffsd->oversampling;
|
|
|
+ return ffsd->scale;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3034,7 +3113,7 @@ double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) c
|
|
|
Vector2i size = _get_size(fd, p_font_size);
|
|
|
|
|
|
if (fd->embolden != 0.0) {
|
|
|
- return fd->embolden * double(size.x) / 64.0;
|
|
|
+ return fd->embolden * double(size.x) / 4096.0;
|
|
|
} else {
|
|
|
return 0.0;
|
|
|
}
|
|
@@ -3065,19 +3144,19 @@ Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64
|
|
|
|
|
|
Vector2 ea;
|
|
|
if (fd->embolden != 0.0) {
|
|
|
- ea.x = fd->embolden * double(size.x) / 64.0;
|
|
|
+ ea.x = fd->embolden * double(size.x) / 4096.0;
|
|
|
}
|
|
|
|
|
|
double scale = _font_get_scale(p_font_rid, p_size);
|
|
|
if (fd->msdf) {
|
|
|
return (fgl.advance + ea) * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return (fgl.advance + ea) * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
|
return (fgl.advance + ea) * Math::round((double)p_size / (double)fd->fixed_size);
|
|
|
}
|
|
|
- } else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE))) {
|
|
|
+ } else if ((scale == 1.0) && ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64))) {
|
|
|
return (fgl.advance + ea).round();
|
|
|
} else {
|
|
|
return fgl.advance + ea;
|
|
@@ -3125,7 +3204,7 @@ Vector2 TextServerAdvanced::_font_get_glyph_offset(const RID &p_font_rid, const
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return fgl.rect.position * (double)p_size.x / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return fgl.rect.position * (double)p_size.x / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -3177,7 +3256,7 @@ Vector2 TextServerAdvanced::_font_get_glyph_size(const RID &p_font_rid, const Ve
|
|
|
|
|
|
if (fd->msdf) {
|
|
|
return fgl.rect.size * (double)p_size.x / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size.x * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return fgl.rect.size * (double)p_size.x / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -3412,7 +3491,7 @@ Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, i
|
|
|
ERR_FAIL_COND_V(error, Dictionary());
|
|
|
|
|
|
if (fd->embolden != 0.f) {
|
|
|
- FT_Pos strength = fd->embolden * p_size * 4; // 26.6 fractional units (1 / 64).
|
|
|
+ FT_Pos strength = fd->embolden * size.x / 16; // 26.6 fractional units (1 / 64).
|
|
|
FT_Outline_Embolden(&ffsd->face->glyph->outline, strength);
|
|
|
}
|
|
|
|
|
@@ -3421,10 +3500,10 @@ Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, i
|
|
|
FT_Outline_Transform(&ffsd->face->glyph->outline, &mat);
|
|
|
}
|
|
|
|
|
|
- double scale = (1.0 / 64.0) / ffsd->oversampling * ffsd->scale;
|
|
|
+ double scale = (1.0 / 64.0) * ffsd->scale;
|
|
|
if (fd->msdf) {
|
|
|
scale = scale * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
scale = scale * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -3517,7 +3596,7 @@ Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_s
|
|
|
if (kern.has(p_glyph_pair)) {
|
|
|
if (fd->msdf) {
|
|
|
return kern[p_glyph_pair] * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return kern[p_glyph_pair] * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -3533,7 +3612,7 @@ Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_s
|
|
|
FT_Get_Kerning(ffsd->face, p_glyph_pair.x, p_glyph_pair.y, FT_KERNING_DEFAULT, &delta);
|
|
|
if (fd->msdf) {
|
|
|
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->msdf_source_size;
|
|
|
- } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ } else if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
return Vector2(delta.x, delta.y) * (double)p_size / (double)fd->fixed_size;
|
|
|
} else {
|
|
@@ -3616,7 +3695,7 @@ bool TextServerAdvanced::_font_has_char(const RID &p_font_rid, int64_t p_char) c
|
|
|
MutexLock lock(fd->mutex);
|
|
|
FontForSizeAdvanced *ffsd = nullptr;
|
|
|
if (fd->cache.is_empty()) {
|
|
|
- ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), false);
|
|
|
+ ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), false);
|
|
|
} else {
|
|
|
ffsd = fd->cache.begin()->value;
|
|
|
}
|
|
@@ -3636,7 +3715,7 @@ String TextServerAdvanced::_font_get_supported_chars(const RID &p_font_rid) cons
|
|
|
MutexLock lock(fd->mutex);
|
|
|
FontForSizeAdvanced *ffsd = nullptr;
|
|
|
if (fd->cache.is_empty()) {
|
|
|
- ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), ffsd), String());
|
|
|
+ ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), ffsd), String());
|
|
|
} else {
|
|
|
ffsd = fd->cache.begin()->value;
|
|
|
}
|
|
@@ -3669,7 +3748,7 @@ PackedInt32Array TextServerAdvanced::_font_get_supported_glyphs(const RID &p_fon
|
|
|
MutexLock lock(fd->mutex);
|
|
|
FontForSizeAdvanced *at_size = nullptr;
|
|
|
if (fd->cache.is_empty()) {
|
|
|
- ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size, 0) : Vector2i(16, 0), at_size), PackedInt32Array());
|
|
|
+ ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, fd->msdf ? Vector2i(fd->msdf_source_size * 64, 0) : Vector2i(16 * 64, 0), at_size), PackedInt32Array());
|
|
|
} else {
|
|
|
at_size = fd->cache.begin()->value;
|
|
|
}
|
|
@@ -3714,12 +3793,12 @@ void TextServerAdvanced::_font_render_range(const RID &p_font_rid, const Vector2
|
|
|
_ensure_glyph(fd, size, (int32_t)idx, fgl);
|
|
|
} else {
|
|
|
for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
|
|
|
} else {
|
|
@@ -3748,12 +3827,12 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2
|
|
|
_ensure_glyph(fd, size, (int32_t)idx, fgl);
|
|
|
} else {
|
|
|
for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24), fgl);
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24), fgl);
|
|
|
_ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24), fgl);
|
|
|
} else {
|
|
@@ -3765,7 +3844,7 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
|
|
|
+void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
|
|
|
if (p_index == 0) {
|
|
|
return; // Non visual character, skip.
|
|
|
}
|
|
@@ -3773,9 +3852,31 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
ERR_FAIL_NULL(fd);
|
|
|
|
|
|
MutexLock lock(fd->mutex);
|
|
|
- Vector2i size = _get_size(fd, p_size);
|
|
|
+
|
|
|
+ // Oversampling.
|
|
|
+ bool viewport_oversampling = false;
|
|
|
+ float oversampling_factor = p_oversampling;
|
|
|
+ if (p_oversampling <= 0.0) {
|
|
|
+ if (vp_oversampling > 0.0) {
|
|
|
+ oversampling_factor = vp_oversampling;
|
|
|
+ viewport_oversampling = true;
|
|
|
+ } else {
|
|
|
+ oversampling_factor = 1.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
|
|
|
+ uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
|
|
|
+ oversampling_factor = double(oversampling_level) / 64.0;
|
|
|
+
|
|
|
+ Vector2i size;
|
|
|
+ if (skip_oversampling) {
|
|
|
+ size = _get_size(fd, p_size);
|
|
|
+ } else {
|
|
|
+ size = Vector2i(p_size * 64 * oversampling_factor, 0);
|
|
|
+ }
|
|
|
+
|
|
|
FontForSizeAdvanced *ffsd = nullptr;
|
|
|
- ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
|
|
|
+ ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
|
|
|
|
|
|
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
|
|
|
bool lcd_aa = false;
|
|
@@ -3791,10 +3892,10 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
}
|
|
|
}
|
|
|
// Subpixel X-shift, bits 27, 28
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
|
|
|
index = index | (xshift << 27);
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
|
|
|
index = index | (xshift << 27);
|
|
|
}
|
|
@@ -3802,7 +3903,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
#endif
|
|
|
|
|
|
FontGlyph fgl;
|
|
|
- if (!_ensure_glyph(fd, size, index, fgl)) {
|
|
|
+ if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
|
|
|
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
|
|
|
}
|
|
|
|
|
@@ -3842,11 +3943,11 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
Size2 csize = fgl.rect.size * (double)p_size / (double)fd->msdf_source_size;
|
|
|
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, 0, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
|
|
|
} else {
|
|
|
- double scale = _font_get_scale(p_font_rid, p_size);
|
|
|
+ double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
|
|
|
Point2 cpos = p_pos;
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
cpos.x = cpos.x + 0.125;
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
cpos.x = cpos.x + 0.25;
|
|
|
}
|
|
|
if (scale == 1.0) {
|
|
@@ -3855,7 +3956,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
}
|
|
|
Vector2 gpos = fgl.rect.position;
|
|
|
Size2 csize = fgl.rect.size;
|
|
|
- if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
double gl_scale = (double)p_size / (double)fd->fixed_size;
|
|
|
gpos *= gl_scale;
|
|
@@ -3865,6 +3966,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
gpos *= gl_scale;
|
|
|
csize *= gl_scale;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ gpos /= oversampling_factor;
|
|
|
+ csize /= oversampling_factor;
|
|
|
}
|
|
|
cpos += gpos;
|
|
|
if (lcd_aa) {
|
|
@@ -3878,7 +3982,7 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
|
|
|
+void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color, float p_oversampling) const {
|
|
|
if (p_index == 0) {
|
|
|
return; // Non visual character, skip.
|
|
|
}
|
|
@@ -3886,9 +3990,31 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
ERR_FAIL_NULL(fd);
|
|
|
|
|
|
MutexLock lock(fd->mutex);
|
|
|
- Vector2i size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
|
|
|
+
|
|
|
+ // Oversampling.
|
|
|
+ bool viewport_oversampling = false;
|
|
|
+ float oversampling_factor = p_oversampling;
|
|
|
+ if (p_oversampling <= 0.0) {
|
|
|
+ if (vp_oversampling > 0.0) {
|
|
|
+ oversampling_factor = vp_oversampling;
|
|
|
+ viewport_oversampling = true;
|
|
|
+ } else {
|
|
|
+ oversampling_factor = 1.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bool skip_oversampling = fd->msdf || fd->fixed_size > 0;
|
|
|
+ uint64_t oversampling_level = CLAMP(oversampling_factor, 0.1, 100.0) * 64;
|
|
|
+ oversampling_factor = double(oversampling_level) / 64.0;
|
|
|
+
|
|
|
+ Vector2i size;
|
|
|
+ if (skip_oversampling) {
|
|
|
+ size = _get_size_outline(fd, Vector2i(p_size, p_outline_size));
|
|
|
+ } else {
|
|
|
+ size = Vector2i(p_size * 64 * oversampling_factor, p_outline_size);
|
|
|
+ }
|
|
|
+
|
|
|
FontForSizeAdvanced *ffsd = nullptr;
|
|
|
- ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd));
|
|
|
+ ERR_FAIL_COND(!_ensure_cache_for_size(fd, size, ffsd, false, viewport_oversampling ? 64 * oversampling_factor : 0));
|
|
|
|
|
|
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
|
|
|
bool lcd_aa = false;
|
|
@@ -3904,10 +4030,10 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
}
|
|
|
}
|
|
|
// Subpixel X-shift, bits 27, 28
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
|
|
|
index = index | (xshift << 27);
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
int xshift = (int)(Math::floor(2 * (p_pos.x + 0.25)) - 2 * Math::floor(p_pos.x + 0.25));
|
|
|
index = index | (xshift << 27);
|
|
|
}
|
|
@@ -3915,7 +4041,7 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
#endif
|
|
|
|
|
|
FontGlyph fgl;
|
|
|
- if (!_ensure_glyph(fd, size, index, fgl)) {
|
|
|
+ if (!_ensure_glyph(fd, size, index, fgl, viewport_oversampling ? 64 * oversampling_factor : 0)) {
|
|
|
return; // Invalid or non-graphical glyph, do not display errors, nothing to draw.
|
|
|
}
|
|
|
|
|
@@ -3952,10 +4078,10 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, fgl.uv_rect, modulate, p_outline_size, fd->msdf_range, (double)p_size / (double)fd->msdf_source_size);
|
|
|
} else {
|
|
|
Point2 cpos = p_pos;
|
|
|
- double scale = _font_get_scale(p_font_rid, p_size);
|
|
|
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
|
|
|
+ double scale = _font_get_scale(p_font_rid, p_size) / oversampling_factor;
|
|
|
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE * 64)) {
|
|
|
cpos.x = cpos.x + 0.125;
|
|
|
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
|
|
|
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE * 64)) {
|
|
|
cpos.x = cpos.x + 0.25;
|
|
|
}
|
|
|
if (scale == 1.0) {
|
|
@@ -3964,7 +4090,7 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
}
|
|
|
Vector2 gpos = fgl.rect.position;
|
|
|
Size2 csize = fgl.rect.size;
|
|
|
- if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size) {
|
|
|
+ if (fd->fixed_size > 0 && fd->fixed_size_scale_mode != FIXED_SIZE_SCALE_DISABLE && size.x != p_size * 64) {
|
|
|
if (fd->fixed_size_scale_mode == FIXED_SIZE_SCALE_ENABLED) {
|
|
|
double gl_scale = (double)p_size / (double)fd->fixed_size;
|
|
|
gpos *= gl_scale;
|
|
@@ -3974,6 +4100,9 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R
|
|
|
gpos *= gl_scale;
|
|
|
csize *= gl_scale;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ gpos /= oversampling_factor;
|
|
|
+ csize /= oversampling_factor;
|
|
|
}
|
|
|
cpos += gpos;
|
|
|
if (lcd_aa) {
|
|
@@ -4127,34 +4256,6 @@ Dictionary TextServerAdvanced::_font_supported_variation_list(const RID &p_font_
|
|
|
return fd->supported_varaitions;
|
|
|
}
|
|
|
|
|
|
-double TextServerAdvanced::_font_get_global_oversampling() const {
|
|
|
- return oversampling;
|
|
|
-}
|
|
|
-
|
|
|
-void TextServerAdvanced::_font_set_global_oversampling(double p_oversampling) {
|
|
|
- _THREAD_SAFE_METHOD_
|
|
|
- if (oversampling != p_oversampling) {
|
|
|
- oversampling = p_oversampling;
|
|
|
- List<RID> fonts;
|
|
|
- font_owner.get_owned_list(&fonts);
|
|
|
- bool font_cleared = false;
|
|
|
- for (const RID &E : fonts) {
|
|
|
- if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
|
|
|
- _font_clear_size_cache(E);
|
|
|
- font_cleared = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (font_cleared) {
|
|
|
- List<RID> text_bufs;
|
|
|
- shaped_owner.get_owned_list(&text_bufs);
|
|
|
- for (const RID &E : text_bufs) {
|
|
|
- invalidate(shaped_owner.get_or_null(E), false);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/*************************************************************************/
|
|
|
/* Shaped text buffer interface */
|
|
|
/*************************************************************************/
|
|
@@ -5514,7 +5615,6 @@ RID TextServerAdvanced::_find_sys_font_for_text(const RID &p_fdef, const String
|
|
|
_font_set_subpixel_positioning(sysf.rid, key.subpixel_positioning);
|
|
|
_font_set_keep_rounding_remainders(sysf.rid, key.keep_rounding_remainders);
|
|
|
_font_set_variation_coordinates(sysf.rid, var);
|
|
|
- _font_set_oversampling(sysf.rid, key.oversampling);
|
|
|
_font_set_embolden(sysf.rid, key.embolden);
|
|
|
_font_set_transform(sysf.rid, key.transform);
|
|
|
_font_set_spacing(sysf.rid, SPACING_TOP, key.extra_spacing[SPACING_TOP]);
|
|
@@ -7931,7 +8031,7 @@ TextServerAdvanced::TextServerAdvanced() {
|
|
|
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &TextServerAdvanced::_update_settings));
|
|
|
}
|
|
|
|
|
|
-void TextServerAdvanced::_cleanup() {
|
|
|
+void TextServerAdvanced::_font_clear_system_fallback_cache() {
|
|
|
_THREAD_SAFE_METHOD_
|
|
|
for (const KeyValue<SystemFontKey, SystemFontCache> &E : system_fonts) {
|
|
|
const Vector<SystemFontCacheRec> &sysf_cache = E.value.var;
|
|
@@ -7943,6 +8043,10 @@ void TextServerAdvanced::_cleanup() {
|
|
|
system_font_data.clear();
|
|
|
}
|
|
|
|
|
|
+void TextServerAdvanced::_cleanup() {
|
|
|
+ font_clear_system_fallback_cache();
|
|
|
+}
|
|
|
+
|
|
|
TextServerAdvanced::~TextServerAdvanced() {
|
|
|
_bmp_free_font_funcs();
|
|
|
#ifdef MODULE_FREETYPE_ENABLED
|