[aseprite] 81/250: Add simple "Edit > Insert Text" menu option (related to #28)

Tobias Hansen thansen at moszumanska.debian.org
Sun Dec 20 15:27:15 UTC 2015


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 1ac39ff85bfafd28c33f5a440e326156dd82ca5c
Author: David Capello <davidcapello at gmail.com>
Date:   Wed Sep 23 17:38:45 2015 -0300

    Add simple "Edit > Insert Text" menu option (related to #28)
---
 data/gui.xml                        |   2 +
 data/pref.xml                       |   4 +
 data/widgets/paste_text.xml         |  23 ++++
 src/app/CMakeLists.txt              |   1 +
 src/app/commands/cmd_paste_text.cpp | 228 ++++++++++++++++++++++++++++++++++++
 src/app/commands/commands_list.h    |   1 +
 6 files changed, 259 insertions(+)

diff --git a/data/gui.xml b/data/gui.xml
index 7e3e2a6..97150aa 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -51,6 +51,7 @@
       <key command="ConvolutionMatrix" shortcut="F9" />
       <key command="ColorCurve" shortcut="Ctrl+M" mac="Cmd+M" />
       <key command="ColorCurve" shortcut="F10" />
+      <key command="PasteText" shortcut="T" />
       <key command="Options" shortcut="Ctrl+K" mac="Cmd+," />
       <key command="Options" shortcut="Ctrl+Shift+O" mac="Cmd+Shift+O" /> <!-- TODO remove this shortcut in v1.1 -->
       <key command="KeyboardShortcuts" shortcut="Ctrl+Alt+Shift+K" mac="Cmd+Alt+Shift+K" />
@@ -538,6 +539,7 @@
           <separator />
           <item command="Despeckle" text="&Despeckle (median filter)" />
         </menu>
+        <item command="PasteText" text="Insert Text" />
         <!--menu text="Scripts">
           <item command="RunScript" text="Transparency from White Background">
             <param name="filename" value="white_to_alpha.js" />
diff --git a/data/pref.xml b/data/pref.xml
index 899cadc..2c76f9d 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -154,6 +154,10 @@
       <option id="color_mode" type="doc::PixelFormat" default="doc::IMAGE_RGB" />
       <option id="background_color" type="int" default="0" />
     </section>
+    <section id="text_tool">
+      <option id="font_face" type="std::string" />
+      <option id="font_size" type="int" default="12" />
+    </section>
   </global>
 
   <tool>
diff --git a/data/widgets/paste_text.xml b/data/widgets/paste_text.xml
new file mode 100644
index 0000000..57d3247
--- /dev/null
+++ b/data/widgets/paste_text.xml
@@ -0,0 +1,23 @@
+<!-- ASEPRITE -->
+<!-- Copyright (C) 2015 by David Capello -->
+<gui>
+<window text="Insert Text" id="paste_text">
+  <grid columns="2">
+    <label text="Text:" />
+    <entry expansive="true" maxsize="256" id="user_text" magnet="true" cell_align="horizontal" />
+
+    <label text="Font:" />
+    <button minwidth="60" id="font_face" text="Select Font" cell_align="horizontal" />
+
+    <label text="Font Size:" />
+    <entry id="font_size" maxsize="4" text="32" cell_align="horizontal" />
+
+    <separator horizontal="true" cell_hspan="2" />
+
+    <box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">
+      <button text="&OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
+      <button text="&Cancel" closewindow="true" />
+    </box>
+  </grid>
+</window>
+</gui>
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 7c79e30..4319e57 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -226,6 +226,7 @@ add_library(app-lib
   commands/cmd_palette_editor.cpp
   commands/cmd_palette_size.cpp
   commands/cmd_paste.cpp
+  commands/cmd_paste_text.cpp
   commands/cmd_play_animation.cpp
   commands/cmd_refresh.cpp
   commands/cmd_remove_frame.cpp
diff --git a/src/app/commands/cmd_paste_text.cpp b/src/app/commands/cmd_paste_text.cpp
new file mode 100644
index 0000000..b2202e7
--- /dev/null
+++ b/src/app/commands/cmd_paste_text.cpp
@@ -0,0 +1,228 @@
+// Aseprite
+// Copyright (C) 2001-2015  David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "app/app.h"
+#include "app/commands/command.h"
+#include "app/context.h"
+#include "app/file_selector.h"
+#include "app/pref/preferences.h"
+#include "app/util/clipboard.h"
+#include "base/bind.h"
+#include "base/path.h"
+#include "base/string.h"
+#include "doc/blend_funcs.h"
+#include "doc/color.h"
+#include "doc/image.h"
+#include "doc/primitives.h"
+
+#include "freetype/ftglyph.h"
+#include "ft2build.h"
+#include FT_FREETYPE_H
+
+#include "paste_text.xml.h"
+
+namespace app {
+
+static std::string last_text_used;
+
+template<typename Iterator, typename Func>
+static void for_each_glyph(FT_Face face, Iterator first, Iterator end, Func callback)
+{
+  bool use_kerning = (FT_HAS_KERNING(face) ? true: false);
+
+  // Calculate size
+  FT_UInt prev_glyph = 0;
+  int x = 0;
+  for (; first != end; ++first) {
+    FT_UInt glyph_index = FT_Get_Char_Index(face, *first);
+
+    if (use_kerning && prev_glyph && glyph_index) {
+      FT_Vector kerning;
+      FT_Get_Kerning(face, prev_glyph, glyph_index,
+                     FT_KERNING_DEFAULT, &kerning);
+      x += kerning.x >> 6;
+    }
+
+    FT_Error err = FT_Load_Glyph(
+      face, glyph_index,
+      FT_LOAD_RENDER | FT_LOAD_NO_BITMAP);
+
+    if (!err) {
+      callback(x, face->glyph);
+      x += face->glyph->advance.x >> 6;
+    }
+
+    prev_glyph = glyph_index;
+  }
+}
+
+class PasteTextCommand : public Command {
+public:
+  PasteTextCommand();
+  Command* clone() const override { return new PasteTextCommand(*this); }
+
+protected:
+  bool onEnabled(Context* ctx) override;
+  void onExecute(Context* ctx) override;
+};
+
+PasteTextCommand::PasteTextCommand()
+  : Command("PasteText",
+            "Insert Text",
+            CmdUIOnlyFlag)
+{
+}
+
+bool PasteTextCommand::onEnabled(Context* ctx)
+{
+  return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable);
+}
+
+class PasteTextWindow : public app::gen::PasteText {
+public:
+  PasteTextWindow(const std::string& face, int size)
+    : m_face(face) {
+    ok()->setEnabled(!m_face.empty());
+    if (!m_face.empty())
+      updateFontFaceButton();
+
+    fontSize()->setTextf("%d", size);
+    fontFace()->Click.connect(Bind<void>(&PasteTextWindow::onSelectFont, this));
+  }
+
+  std::string faceValue() const {
+    return m_face;
+  }
+
+  int sizeValue() const {
+    int size = fontSize()->getTextInt();
+    size = MID(1, size, 5000);
+    return size;
+  }
+
+private:
+  void updateFontFaceButton() {
+    fontFace()->setTextf("Select Font: %s",
+                         base::get_file_name(m_face).c_str());
+  }
+
+  void onSelectFont() {
+    std::string face = show_file_selector(
+      "Select a TrueType Font",
+      m_face,
+      "ttf",
+      FileSelectorType::Open,
+      nullptr);
+
+    if (!face.empty()) {
+      m_face = face;
+      ok()->setEnabled(true);
+      updateFontFaceButton();
+    }
+  }
+
+  std::string m_face;
+};
+
+void PasteTextCommand::onExecute(Context* ctx)
+{
+  Preferences& pref = Preferences::instance();
+  PasteTextWindow window(pref.textTool.fontFace(),
+                         pref.textTool.fontSize());
+
+  window.userText()->setText(last_text_used);
+
+  window.openWindowInForeground();
+  if (window.getKiller() != window.ok())
+    return;
+
+  last_text_used = window.userText()->getText();
+
+  std::string faceName = window.faceValue();
+  int size = window.sizeValue();
+  pref.textTool.fontFace(faceName);
+  pref.textTool.fontSize(size);
+
+  FT_Library ft;
+  FT_Init_FreeType(&ft);
+
+  FT_Open_Args args;
+  memset(&args, 0, sizeof(args));
+  args.flags = FT_OPEN_PATHNAME;
+  args.pathname = (FT_String*)faceName.c_str();
+
+  FT_Face face;
+  FT_Error err = FT_Open_Face(ft, &args, 0, &face);
+  if (!err) {
+    std::string text = window.userText()->getText();
+
+    // Set font size
+    FT_Set_Pixel_Sizes(face, size, size);
+
+    // Calculate text size
+    base::utf8_iterator begin(text.begin()), end(text.end());
+    gfx::Rect bounds(0, 0, 0, 0);
+    for_each_glyph(
+      face, begin, end,
+      [&bounds](int x, FT_GlyphSlot glyph) {
+        bounds |= gfx::Rect(x + glyph->bitmap_left,
+                            -glyph->bitmap_top,
+                            (int)glyph->bitmap.width,
+                            (int)glyph->bitmap.rows);
+      });
+
+    // Render the image and copy it to the clipboard
+    if (!bounds.isEmpty()) {
+      doc::Image* image = doc::Image::create(IMAGE_RGB, bounds.w, bounds.h);
+      doc::clear_image(image, 0);
+
+      for_each_glyph(
+        face, begin, end,
+        [&bounds, &image](int x, FT_GlyphSlot glyph) {
+          int 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;
+              doc::put_pixel(image, ximg, yimg,
+                             doc::rgba_blender_normal(doc::get_pixel(image, ximg, yimg),
+                                                      doc::rgba(255, 255, 255, *p), 255));
+            }
+          }
+        });
+
+      clipboard::copy_image(image, nullptr, nullptr);
+      clipboard::paste();
+    }
+    else {
+      ui::Alert::show(PACKAGE
+                      "<<There is no text"
+                      "||&OK");
+    }
+
+    FT_Done_Face(face);
+  }
+  else {
+    ui::Alert::show(PACKAGE
+                    "<<Error loading font face"
+                    "||&OK");
+  }
+
+  FT_Done_FreeType(ft);
+}
+
+Command* CommandFactory::createPasteTextCommand()
+{
+  return new PasteTextCommand;
+}
+
+} // namespace app
diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h
index fc56df7..0426326 100644
--- a/src/app/commands/commands_list.h
+++ b/src/app/commands/commands_list.h
@@ -83,6 +83,7 @@ FOR_EACH_COMMAND(Options)
 FOR_EACH_COMMAND(PaletteEditor)
 FOR_EACH_COMMAND(PaletteSize)
 FOR_EACH_COMMAND(Paste)
+FOR_EACH_COMMAND(PasteText)
 FOR_EACH_COMMAND(PlayAnimation)
 FOR_EACH_COMMAND(Redo)
 FOR_EACH_COMMAND(Refresh)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list