Add anti-aliasing checkbox in "Edit > Insert Text" option

This commit is contained in:
David Capello 2015-12-01 15:46:21 -03:00
parent f47ba09984
commit 3b0bf6daaa
6 changed files with 44 additions and 11 deletions

View File

@ -163,6 +163,7 @@
<section id="text_tool">
<option id="font_face" type="std::string" />
<option id="font_size" type="int" default="12" />
<option id="antialias" type="bool" default="false" />
</section>
<section id="symmetry_mode">
<option id="enabled" type="bool" default="false" />

View File

@ -15,6 +15,10 @@
<label text="Color:" />
<colorpicker id="font_color" cell_align="horizontal" />
<hbox />
<check id="antialias" text="Anti-aliasing filter" cell_align="horizontal"
tooltip="Smooth font edges" />
<separator horizontal="true" cell_hspan="2" />
<box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">

View File

@ -59,6 +59,7 @@ bool PasteTextCommand::onEnabled(Context* ctx)
class PasteTextWindow : public app::gen::PasteText {
public:
PasteTextWindow(const std::string& face, int size,
bool antialias,
const app::Color& color)
: m_face(face) {
ok()->setEnabled(!m_face.empty());
@ -69,6 +70,7 @@ public:
fontFace()->Click.connect(Bind<void>(&PasteTextWindow::onSelectFontFile, this));
fontFace()->DropDownClick.connect(Bind<void>(&PasteTextWindow::onSelectSystemFont, this));
fontColor()->setColor(color);
this->antialias()->setSelected(antialias);
}
std::string faceValue() const {
@ -148,6 +150,7 @@ void PasteTextCommand::onExecute(Context* ctx)
Preferences& pref = Preferences::instance();
PasteTextWindow window(pref.textTool.fontFace(),
pref.textTool.fontSize(),
pref.textTool.antialias(),
pref.colorBar.fgColor());
window.userText()->setText(last_text_used);
@ -158,11 +161,13 @@ void PasteTextCommand::onExecute(Context* ctx)
last_text_used = window.userText()->getText();
bool antialias = window.antialias()->isSelected();
std::string faceName = window.faceValue();
int size = window.sizeValue();
size = MID(1, size, 999);
pref.textTool.fontFace(faceName);
pref.textTool.fontSize(size);
pref.textTool.antialias(antialias);
try {
std::string text = window.userText()->getText();
@ -172,7 +177,7 @@ void PasteTextCommand::onExecute(Context* ctx)
appColor.getBlue(),
appColor.getAlpha());
doc::ImageRef image(render_text(faceName, size, text, color));
doc::ImageRef image(render_text(faceName, size, text, color, antialias));
if (image) {
Sprite* sprite = editor->sprite();
if (image->pixelFormat() != sprite->pixelFormat()) {

View File

@ -108,7 +108,8 @@ private:
doc::rgba(gfx::getr(color),
gfx::getg(color),
gfx::getb(color),
gfx::geta(color))));
gfx::geta(color)),
true)); // antialias
View* view = View::getView(listbox);
view->updateView();

View File

@ -28,7 +28,9 @@
namespace app {
template<typename Iterator, typename Func>
static void for_each_glyph(FT_Face face, Iterator first, Iterator end, Func callback)
static void for_each_glyph(FT_Face face, bool antialias,
Iterator first, Iterator end,
Func callback)
{
bool use_kerning = (FT_HAS_KERNING(face) ? true: false);
@ -47,7 +49,10 @@ static void for_each_glyph(FT_Face face, Iterator first, Iterator end, Func call
FT_Error err = FT_Load_Glyph(
face, glyph_index,
FT_LOAD_RENDER | FT_LOAD_NO_BITMAP);
FT_LOAD_RENDER |
FT_LOAD_NO_BITMAP |
(antialias ? FT_LOAD_TARGET_NORMAL:
FT_LOAD_TARGET_MONO));
if (!err) {
callback(x, face->glyph);
@ -83,7 +88,8 @@ private:
doc::Image* render_text(const std::string& fontfile, int fontsize,
const std::string& text,
doc::color_t color)
doc::color_t color,
bool antialias)
{
base::UniquePtr<doc::Image> image(nullptr);
FT_Library ft;
@ -106,7 +112,7 @@ doc::Image* render_text(const std::string& fontfile, int fontsize,
base::utf8_const_iterator begin(text.begin()), end(text.end());
gfx::Rect bounds(0, 0, 0, 0);
for_each_glyph(
face, begin, end,
face, antialias, begin, end,
[&bounds](int x, FT_GlyphSlot glyph) {
bounds |= gfx::Rect(x + glyph->bitmap_left,
-glyph->bitmap_top,
@ -120,14 +126,29 @@ doc::Image* render_text(const std::string& fontfile, int fontsize,
doc::clear_image(image, 0);
for_each_glyph(
face, begin, end,
[&bounds, &image, color](int x, FT_GlyphSlot glyph) {
face, antialias, begin, end,
[&bounds, &image, color, antialias](int x, FT_GlyphSlot glyph) {
int t, yimg = - bounds.y - glyph->bitmap_top;
for (int v=0; v<(int)glyph->bitmap.rows; ++v, ++yimg) {
const uint8_t* p = glyph->bitmap.buffer + v*glyph->bitmap.pitch;
int ximg = x - bounds.x + glyph->bitmap_left;
for (int u=0; u<(int)glyph->bitmap.width; ++u, ++p, ++ximg) {
int alpha = *p;
int bit = 0;
for (int u=0; u<(int)glyph->bitmap.width; ++u, ++ximg) {
int alpha;
if (antialias) {
alpha = *(p++);
}
else {
alpha = ((*p) & (1 << (7 - (bit++))) ? 255: 0);
if (bit == 8) {
bit = 0;
++p;
}
}
doc::put_pixel(
image, ximg, yimg,
doc::rgba_blender_normal(

View File

@ -21,7 +21,8 @@ namespace app {
doc::Image* render_text(const std::string& fontfile, int fontsize,
const std::string& text,
doc::color_t color);
doc::color_t color,
bool antialias);
} // namespace app