mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
Merge branch 'love2d:main' into sdf-font-hintingmode
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -343,6 +343,7 @@ GlyphData *BMFontRasterizer::getGlyphDataForIndex(int index) const
|
||||
uint8 *pixels = (uint8 *) g->getData();
|
||||
const uint8 *ipixels = (const uint8 *) imagedata->getData();
|
||||
|
||||
// Always lock the mutex since the user can't know when to do it.
|
||||
love::thread::Lock lock(imagedata->getMutex());
|
||||
|
||||
// Copy the subsection of the texture from the ImageData to the GlyphData.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -34,7 +34,8 @@ namespace font
|
||||
// Default TrueType font, gzip-compressed.
|
||||
#include "NotoSans-Regular.ttf.gzip.h"
|
||||
|
||||
Font::Font()
|
||||
Font::Font(const char *name)
|
||||
: Module(M_FONT, name)
|
||||
{
|
||||
auto compressedbytes = (const char *) NotoSans_Regular_ttf_gzip;
|
||||
size_t compressedsize = NotoSans_Regular_ttf_gzip_len;
|
||||
@@ -45,14 +46,9 @@ Font::Font()
|
||||
defaultFontData.set(new data::ByteData(fontdata, rawsize, true), Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
Rasterizer *Font::newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting)
|
||||
Rasterizer *Font::newTrueTypeRasterizer(int size, const TrueTypeRasterizer::Settings &settings)
|
||||
{
|
||||
return newTrueTypeRasterizer(defaultFontData.get(), size, hinting);
|
||||
}
|
||||
|
||||
Rasterizer *Font::newTrueTypeRasterizer(int size, float dpiscale, TrueTypeRasterizer::Hinting hinting)
|
||||
{
|
||||
return newTrueTypeRasterizer(defaultFontData.get(), size, dpiscale, hinting);
|
||||
return newTrueTypeRasterizer(defaultFontData.get(), size, settings);
|
||||
}
|
||||
|
||||
Rasterizer *Font::newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector<image::ImageData *> &images, float dpiscale)
|
||||
@@ -78,12 +74,7 @@ Rasterizer *Font::newImageRasterizer(love::image::ImageData *data, const std::st
|
||||
throw love::Exception("UTF-8 decoding error: %s", e.what());
|
||||
}
|
||||
|
||||
return newImageRasterizer(data, &glyphs[0], (int) glyphs.size(), extraspacing, dpiscale);
|
||||
}
|
||||
|
||||
Rasterizer *Font::newImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs, int extraspacing, float dpiscale)
|
||||
{
|
||||
return new ImageRasterizer(data, glyphs, numglyphs, extraspacing, dpiscale);
|
||||
return new ImageRasterizer(data, glyphs.data(), (int) glyphs.size(), extraspacing, dpiscale);
|
||||
}
|
||||
|
||||
GlyphData *Font::newGlyphData(Rasterizer *r, const std::string &text)
|
||||
|
||||
+6
-10
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -43,27 +43,23 @@ class Font : public Module
|
||||
|
||||
public:
|
||||
|
||||
Font();
|
||||
virtual ~Font() {}
|
||||
|
||||
virtual Rasterizer *newRasterizer(love::filesystem::FileData *data) = 0;
|
||||
|
||||
virtual Rasterizer *newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting);
|
||||
virtual Rasterizer *newTrueTypeRasterizer(int size, float dpiscale, TrueTypeRasterizer::Hinting hinting);
|
||||
virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) = 0;
|
||||
virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) = 0;
|
||||
Rasterizer *newTrueTypeRasterizer(int size, const TrueTypeRasterizer::Settings &settings);
|
||||
virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, const TrueTypeRasterizer::Settings &settings) = 0;
|
||||
|
||||
virtual Rasterizer *newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector<image::ImageData *> &images, float dpiscale);
|
||||
|
||||
virtual Rasterizer *newImageRasterizer(love::image::ImageData *data, const std::string &glyphs, int extraspacing, float dpiscale);
|
||||
virtual Rasterizer *newImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int length, int extraspacing, float dpiscale);
|
||||
|
||||
virtual GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph);
|
||||
virtual GlyphData *newGlyphData(Rasterizer *r, uint32 glyph);
|
||||
|
||||
// Implement Module.
|
||||
virtual ModuleType getModuleType() const { return M_FONT; }
|
||||
virtual const char *getName() const = 0;
|
||||
protected:
|
||||
|
||||
Font(const char *name);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -151,8 +151,7 @@ int GenericShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ran
|
||||
float w = 0.0f;
|
||||
float outwidth = 0.0f;
|
||||
float widthbeforelastspace = 0.0f;
|
||||
int wrapindex = -1;
|
||||
int lastspaceindex = -1;
|
||||
int firstindexafterspace = -1;
|
||||
|
||||
for (int i = (int)range.getMin(); i <= (int)range.getMax(); i++)
|
||||
{
|
||||
@@ -166,37 +165,48 @@ int GenericShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ran
|
||||
|
||||
float newwidth = w + getKerning(prevglyph, g) + getGlyphAdvance(g);
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit && !isWhitespace(g))
|
||||
{
|
||||
// Rewind to the last seen space when wrapping.
|
||||
if (lastspaceindex != -1)
|
||||
{
|
||||
wrapindex = lastspaceindex;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't count trailing spaces in the output width.
|
||||
if (isWhitespace(g))
|
||||
{
|
||||
lastspaceindex = i;
|
||||
if (!isWhitespace(prevglyph))
|
||||
widthbeforelastspace = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isWhitespace(prevglyph))
|
||||
firstindexafterspace = i;
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit)
|
||||
{
|
||||
// If this is the first character, wrap from the next one instead of this one.
|
||||
int wrapindex = i > (int)range.first ? i : (int)range.first + 1;
|
||||
|
||||
// Rewind to after the last seen space when wrapping.
|
||||
if (firstindexafterspace != -1)
|
||||
{
|
||||
wrapindex = firstindexafterspace;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
}
|
||||
|
||||
outwidth = newwidth;
|
||||
}
|
||||
|
||||
w = newwidth;
|
||||
prevglyph = g;
|
||||
wrapindex = i;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
// There wasn't any wrap in the middle of the range.
|
||||
return range.last + 1;
|
||||
}
|
||||
|
||||
} // font
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -90,7 +90,7 @@ GlyphData *ImageRasterizer::getGlyphDataForIndex(int index) const
|
||||
if (gm.width == 0)
|
||||
return g;
|
||||
|
||||
// We don't want another thread modifying our ImageData mid-copy.
|
||||
// Always lock the mutex since the user can't know when to do it.
|
||||
love::thread::Lock lock(imageData->getMutex());
|
||||
|
||||
Color32 *gdpixels = (Color32 *) g->getData();
|
||||
@@ -118,9 +118,6 @@ void ImageRasterizer::load(const uint32 *glyphs, int glyphcount)
|
||||
int imgw = imageData->getWidth();
|
||||
int imgh = imageData->getHeight();
|
||||
|
||||
// We don't want another thread modifying our ImageData mid-parse.
|
||||
love::thread::Lock lock(imageData->getMutex());
|
||||
|
||||
// Set the only metric that matters
|
||||
metrics.height = imgh;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -303,10 +303,10 @@ void TextShaper::getWrap(const ColoredCodepoints &codepoints, float wraplimit, s
|
||||
float width = 0.0f;
|
||||
int wrapindex = computeWordWrapIndex(codepoints, r, wraplimit, &width);
|
||||
|
||||
if (wrapindex >= (int) i)
|
||||
if (wrapindex > (int) i)
|
||||
{
|
||||
r = Range(i, (size_t) wrapindex + 1 - i);
|
||||
i = (size_t)wrapindex + 1;
|
||||
r = Range(i, (size_t) wrapindex - i);
|
||||
i = (size_t)wrapindex;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,7 @@
|
||||
// LOVE
|
||||
#include "Rasterizer.h"
|
||||
#include "common/StringMap.h"
|
||||
#include "common/Optional.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -45,6 +46,12 @@ public:
|
||||
HINTING_MAX_ENUM
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
Hinting hinting = HINTING_NORMAL;
|
||||
OptionalFloat dpiScale;
|
||||
};
|
||||
|
||||
virtual ~TrueTypeRasterizer() {}
|
||||
|
||||
static bool getConstant(const char *in, Hinting &out);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -36,6 +36,7 @@ namespace freetype
|
||||
{
|
||||
|
||||
Font::Font()
|
||||
: love::font::Font("love.font.freetype")
|
||||
{
|
||||
if (FT_Init_FreeType(&library))
|
||||
throw love::Exception("TrueTypeFont Loading error: FT_Init_FreeType failed");
|
||||
@@ -49,31 +50,21 @@ Font::~Font()
|
||||
Rasterizer *Font::newRasterizer(love::filesystem::FileData *data)
|
||||
{
|
||||
if (TrueTypeRasterizer::accepts(library, data))
|
||||
return newTrueTypeRasterizer(data, 12, TrueTypeRasterizer::HINTING_NORMAL);
|
||||
return newTrueTypeRasterizer(data, 12, font::TrueTypeRasterizer::Settings());
|
||||
else if (BMFontRasterizer::accepts(data))
|
||||
return newBMFontRasterizer(data, {}, 1.0f);
|
||||
|
||||
throw love::Exception("Invalid font file: %s", data->getFilename().c_str());
|
||||
}
|
||||
|
||||
Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting)
|
||||
Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, const font::TrueTypeRasterizer::Settings &settings)
|
||||
{
|
||||
float dpiscale = 1.0f;
|
||||
float defaultdpiscale = 1.0f;
|
||||
auto window = Module::getInstance<window::Window>(Module::M_WINDOW);
|
||||
if (window != nullptr)
|
||||
dpiscale = window->getDPIScale();
|
||||
defaultdpiscale = window->getDPIScale();
|
||||
|
||||
return newTrueTypeRasterizer(data, size, dpiscale, hinting);
|
||||
}
|
||||
|
||||
Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting)
|
||||
{
|
||||
return new TrueTypeRasterizer(library, data, size, dpiscale, hinting);
|
||||
}
|
||||
|
||||
const char *Font::getName() const
|
||||
{
|
||||
return "love.font.freetype";
|
||||
return new TrueTypeRasterizer(library, data, size, settings, defaultdpiscale);
|
||||
}
|
||||
|
||||
} // freetype
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -45,11 +45,7 @@ public:
|
||||
|
||||
// Implements Font
|
||||
Rasterizer *newRasterizer(love::filesystem::FileData *data) override;
|
||||
Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) override;
|
||||
Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) override;
|
||||
|
||||
// Implement Module
|
||||
const char *getName() const override;
|
||||
Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, const font::TrueTypeRasterizer::Settings &settings) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -153,18 +153,18 @@ void HarfbuzzShaper::computeBufferRanges(const ColoredCodepoints &codepoints, Ra
|
||||
|
||||
hb_shape(hbFonts[rasti], hbb, nullptr, 0);
|
||||
|
||||
int glyphcount = (int)hb_buffer_get_length(hbb);
|
||||
size_t glyphcount = (size_t)hb_buffer_get_length(hbb);
|
||||
const hb_glyph_info_t *glyphinfos = hb_buffer_get_glyph_infos(hbb, nullptr);
|
||||
hb_direction_t direction = hb_buffer_get_direction(hbb);
|
||||
|
||||
fallbackranges.clear();
|
||||
|
||||
for (int i = 0; i < glyphcount; i++)
|
||||
for (size_t i = 0; i < glyphcount; i++)
|
||||
{
|
||||
if (isValidGlyph(glyphinfos[i].codepoint, codepoints.cps, glyphinfos[i].cluster))
|
||||
{
|
||||
if (bufferranges.empty() || bufferranges.back().index != rasti || bufferranges.back().range.getMax() + 1 != i)
|
||||
bufferranges.push_back({(int)rasti, (int)glyphinfos[i].cluster, Range(i, 1)});
|
||||
bufferranges.push_back({rasti, (int)glyphinfos[i].cluster, Range(i, 1)});
|
||||
else
|
||||
bufferranges.back().range.last++;
|
||||
}
|
||||
@@ -247,7 +247,7 @@ void HarfbuzzShaper::computeGlyphPositions(const ColoredCodepoints &codepoints,
|
||||
// TODO: this doesn't handle situations where the user inserted a color
|
||||
// change in the middle of some characters that get combined into a single
|
||||
// cluster.
|
||||
if (colors && colorindex < ncolors && codepoints.colors[colorindex].index == info.cluster)
|
||||
if (colors && colorindex < ncolors && codepoints.colors[colorindex].index == (int)info.cluster)
|
||||
{
|
||||
colorToAdd.set(codepoints.colors[colorindex].color);
|
||||
colorindex++;
|
||||
@@ -273,7 +273,7 @@ void HarfbuzzShaper::computeGlyphPositions(const ColoredCodepoints &codepoints,
|
||||
continue;
|
||||
|
||||
// This is a glyph index at this point, despite the name.
|
||||
GlyphIndex gindex = { (int) info.codepoint, bufferrange.index };
|
||||
GlyphIndex gindex = { (int) info.codepoint, (int)bufferrange.index };
|
||||
|
||||
if (clustercodepoint == '\t' && isUsingSpacesForTab())
|
||||
{
|
||||
@@ -335,8 +335,7 @@ int HarfbuzzShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ra
|
||||
float w = 0.0f;
|
||||
float outwidth = 0.0f;
|
||||
float widthbeforelastspace = 0.0f;
|
||||
int wrapindex = -1;
|
||||
int lastspaceindex = -1;
|
||||
int firstindexafterspace = -1;
|
||||
|
||||
uint32 prevcodepoint = 0;
|
||||
|
||||
@@ -376,38 +375,49 @@ int HarfbuzzShaper::computeWordWrapIndex(const ColoredCodepoints &codepoints, Ra
|
||||
|
||||
float newwidth = w + floorf((glyphpos.x_advance >> 6) / dpiScales[0] + 0.5f);
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit && !isWhitespace(clustercodepoint))
|
||||
{
|
||||
// Rewind to the last seen space when wrapping.
|
||||
if (lastspaceindex != -1)
|
||||
{
|
||||
wrapindex = lastspaceindex;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't count trailing spaces in the output width.
|
||||
if (isWhitespace(clustercodepoint))
|
||||
{
|
||||
lastspaceindex = info.cluster;
|
||||
if (!isWhitespace(prevcodepoint))
|
||||
widthbeforelastspace = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isWhitespace(prevcodepoint))
|
||||
firstindexafterspace = info.cluster;
|
||||
|
||||
// Only wrap when there's a non-space character.
|
||||
if (newwidth > wraplimit)
|
||||
{
|
||||
// If this is the first character, wrap from the next one instead of this one.
|
||||
int wrapindex = (int)info.cluster > (int)range.first ? (int)info.cluster : (int)range.first + 1;
|
||||
|
||||
// Rewind to after the last seen space when wrapping.
|
||||
if (firstindexafterspace != -1)
|
||||
{
|
||||
wrapindex = firstindexafterspace;
|
||||
outwidth = widthbeforelastspace;
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
}
|
||||
|
||||
outwidth = newwidth;
|
||||
}
|
||||
|
||||
w = newwidth;
|
||||
prevcodepoint = clustercodepoint;
|
||||
wrapindex = info.cluster;
|
||||
}
|
||||
}
|
||||
|
||||
if (width)
|
||||
*width = outwidth;
|
||||
|
||||
return wrapindex;
|
||||
// There wasn't any wrap in the middle of the range.
|
||||
return (int) range.last + 1;
|
||||
}
|
||||
|
||||
} // freetype
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
|
||||
struct BufferRange
|
||||
{
|
||||
int index;
|
||||
size_t index;
|
||||
int codepointStart;
|
||||
Range range;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -33,12 +33,12 @@ namespace font
|
||||
namespace freetype
|
||||
{
|
||||
|
||||
TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size, float dpiscale, Hinting hinting)
|
||||
TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size, const Settings &settings, float defaultdpiscale)
|
||||
: data(data)
|
||||
, hinting(hinting)
|
||||
, hinting(settings.hinting)
|
||||
{
|
||||
this->dpiScale = dpiscale;
|
||||
size = floorf(size * dpiscale + 0.5f);
|
||||
dpiScale = settings.dpiScale.get(defaultdpiscale);
|
||||
size = floorf(size * dpiScale + 0.5f);
|
||||
|
||||
if (size <= 0)
|
||||
throw love::Exception("Invalid TrueType font size: %d", size);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -44,7 +44,7 @@ class TrueTypeRasterizer : public love::font::TrueTypeRasterizer
|
||||
{
|
||||
public:
|
||||
|
||||
TrueTypeRasterizer(FT_Library library, love::Data *data, int size, float dpiscale, Hinting hinting);
|
||||
TrueTypeRasterizer(FT_Library library, love::Data *data, int size, const Settings &settings, float defaultdpiscale);
|
||||
virtual ~TrueTypeRasterizer();
|
||||
|
||||
// Implement Rasterizer
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
@@ -64,30 +64,65 @@ int w_newRasterizer(lua_State *L)
|
||||
}
|
||||
}
|
||||
|
||||
static TrueTypeRasterizer::Settings luax_checktruetypesettings(lua_State* L, int startidx)
|
||||
{
|
||||
TrueTypeRasterizer::Settings s;
|
||||
|
||||
if (lua_type(L, startidx) == LUA_TSTRING)
|
||||
{
|
||||
// Legacy parameters.
|
||||
const char *hintstr = lua_isnoneornil(L, startidx) ? nullptr : luaL_checkstring(L, startidx);
|
||||
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, s.hinting))
|
||||
luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(s.hinting), hintstr);
|
||||
|
||||
if (!lua_isnoneornil(L, startidx + 1))
|
||||
s.dpiScale.set((float)luaL_checknumber(L, startidx + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
luaL_checktype(L, startidx, LUA_TTABLE);
|
||||
|
||||
lua_getfield(L, startidx, "hinting");
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
{
|
||||
const char *hintstr = luaL_checkstring(L, -1);
|
||||
if (!TrueTypeRasterizer::getConstant(hintstr, s.hinting))
|
||||
luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(s.hinting), hintstr);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, startidx, "dpiscale");
|
||||
if (!lua_isnoneornil(L, -1))
|
||||
s.dpiScale.set((float)luaL_checknumber(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int w_newTrueTypeRasterizer(lua_State *L)
|
||||
{
|
||||
Rasterizer *t = nullptr;
|
||||
TrueTypeRasterizer::Hinting hinting = TrueTypeRasterizer::HINTING_NORMAL;
|
||||
|
||||
if (lua_type(L, 1) == LUA_TNUMBER || lua_isnone(L, 1))
|
||||
{
|
||||
// First argument is a number: use the default TrueType font.
|
||||
int size = (int) luaL_optinteger(L, 1, 13);
|
||||
|
||||
const char *hintstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
|
||||
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
||||
return luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(hinting), hintstr);
|
||||
TrueTypeRasterizer::Settings settings;
|
||||
if (!lua_isnoneornil(L, 2))
|
||||
settings = luax_checktruetypesettings(L, 2);
|
||||
|
||||
if (lua_isnoneornil(L, 3))
|
||||
luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, hinting); });
|
||||
else
|
||||
{
|
||||
float dpiscale = (float) luaL_checknumber(L, 3);
|
||||
luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, dpiscale, hinting); });
|
||||
}
|
||||
luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, settings); });
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = (int) luaL_optinteger(L, 2, 12);
|
||||
|
||||
TrueTypeRasterizer::Settings settings;
|
||||
if (!lua_isnoneornil(L, 3))
|
||||
settings = luax_checktruetypesettings(L, 3);
|
||||
|
||||
love::Data *d = nullptr;
|
||||
|
||||
if (luax_istype(L, 1, love::Data::type))
|
||||
@@ -98,27 +133,10 @@ int w_newTrueTypeRasterizer(lua_State *L)
|
||||
else
|
||||
d = filesystem::luax_getfiledata(L, 1);
|
||||
|
||||
int size = (int) luaL_optinteger(L, 2, 12);
|
||||
|
||||
const char *hintstr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3);
|
||||
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
||||
return luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(hinting), hintstr);
|
||||
|
||||
if (lua_isnoneornil(L, 4))
|
||||
{
|
||||
luax_catchexcept(L,
|
||||
[&]() { t = instance()->newTrueTypeRasterizer(d, size, hinting); },
|
||||
[&](bool) { d->release(); }
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
float dpiscale = (float) luaL_checknumber(L, 4);
|
||||
luax_catchexcept(L,
|
||||
[&]() { t = instance()->newTrueTypeRasterizer(d, size, dpiscale, hinting); },
|
||||
[&](bool) { d->release(); }
|
||||
);
|
||||
}
|
||||
luax_catchexcept(L,
|
||||
[&]() { t = instance()->newTrueTypeRasterizer(d, size, settings); },
|
||||
[&](bool) { d->release(); }
|
||||
);
|
||||
}
|
||||
|
||||
luax_pushtype(L, t);
|
||||
@@ -154,7 +172,7 @@ int w_newBMFontRasterizer(lua_State *L)
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (!lua_isnoneornil(L, 2))
|
||||
{
|
||||
convimagedata(L, 2);
|
||||
image::ImageData *id = luax_checktype<image::ImageData>(L, 2);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 LOVE Development Team
|
||||
* Copyright (c) 2006-2024 LOVE Development Team
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
Reference in New Issue
Block a user