diff --git a/data/pref.xml b/data/pref.xml
index 936bf08e1..aaff328b7 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -163,6 +163,7 @@
diff --git a/data/widgets/paste_text.xml b/data/widgets/paste_text.xml
index 4681dd9b5..7b79798cb 100644
--- a/data/widgets/paste_text.xml
+++ b/data/widgets/paste_text.xml
@@ -15,6 +15,10 @@
+
+
+
diff --git a/src/app/commands/cmd_paste_text.cpp b/src/app/commands/cmd_paste_text.cpp
index c08e74a95..1ab2552f5 100644
--- a/src/app/commands/cmd_paste_text.cpp
+++ b/src/app/commands/cmd_paste_text.cpp
@@ -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(&PasteTextWindow::onSelectFontFile, this));
fontFace()->DropDownClick.connect(Bind(&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()) {
diff --git a/src/app/ui/font_popup.cpp b/src/app/ui/font_popup.cpp
index dadec4bc3..766f0c598 100644
--- a/src/app/ui/font_popup.cpp
+++ b/src/app/ui/font_popup.cpp
@@ -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();
diff --git a/src/app/util/freetype_utils.cpp b/src/app/util/freetype_utils.cpp
index c66e7b399..0774774c9 100644
--- a/src/app/util/freetype_utils.cpp
+++ b/src/app/util/freetype_utils.cpp
@@ -28,7 +28,9 @@
namespace app {
template
-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 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(
diff --git a/src/app/util/freetype_utils.h b/src/app/util/freetype_utils.h
index d2589ae83..ef397dab5 100644
--- a/src/app/util/freetype_utils.h
+++ b/src/app/util/freetype_utils.h
@@ -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