mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 12:44:53 +00:00
Move ft::ForEachGlyph to ft/algorithm.h
This commit is contained in:
parent
84c4d1af93
commit
44feaf6676
@ -16,6 +16,7 @@
|
|||||||
#include "doc/color.h"
|
#include "doc/color.h"
|
||||||
#include "doc/image.h"
|
#include "doc/image.h"
|
||||||
#include "doc/primitives.h"
|
#include "doc/primitives.h"
|
||||||
|
#include "ft/algorithm.h"
|
||||||
#include "ft/face.h"
|
#include "ft/face.h"
|
||||||
#include "ft/lib.h"
|
#include "ft/lib.h"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2016 David Capello
|
Copyright (c) 2016-2017 David Capello
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Aseprite FreeType Wrapper
|
# Aseprite FreeType Wrapper
|
||||||
*Copyright (C) 2016 David Capello*
|
*Copyright (C) 2016-2017 David Capello*
|
||||||
|
|
||||||
> Distributed under [MIT license](LICENSE.txt)
|
> Distributed under [MIT license](LICENSE.txt)
|
||||||
|
92
src/ft/algorithm.h
Normal file
92
src/ft/algorithm.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Aseprite FreeType Wrapper
|
||||||
|
// Copyright (c) 2016-2017 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifndef FT_ALGORITHM_H_INCLUDED
|
||||||
|
#define FT_ALGORITHM_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/string.h"
|
||||||
|
#include "ft/freetype_headers.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
|
||||||
|
namespace ft {
|
||||||
|
|
||||||
|
template<typename FaceFT>
|
||||||
|
class ForEachGlyph {
|
||||||
|
public:
|
||||||
|
ForEachGlyph(FaceFT& face)
|
||||||
|
: m_face(face)
|
||||||
|
, m_useKerning(FT_HAS_KERNING((FT_Face)face) ? true: false)
|
||||||
|
, m_prevGlyph(0)
|
||||||
|
, m_x(0.0), m_y(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ProcessGlyph>
|
||||||
|
void processChar(const int chr, ProcessGlyph processGlyph) {
|
||||||
|
FT_UInt glyphIndex = m_face.cache().getGlyphIndex(m_face, chr);
|
||||||
|
double initialX = m_x;
|
||||||
|
|
||||||
|
if (m_useKerning && m_prevGlyph && glyphIndex) {
|
||||||
|
FT_Vector kerning;
|
||||||
|
FT_Get_Kerning(m_face, m_prevGlyph, glyphIndex,
|
||||||
|
FT_KERNING_DEFAULT, &kerning);
|
||||||
|
m_x += kerning.x / 64.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename FaceFT::Glyph* glyph = m_face.cache().loadGlyph(
|
||||||
|
m_face, glyphIndex, m_face.antialias());
|
||||||
|
if (glyph) {
|
||||||
|
glyph->bitmap = &FT_BitmapGlyph(glyph->ft_glyph)->bitmap;
|
||||||
|
glyph->x = m_x + glyph->bearingX;
|
||||||
|
glyph->y = m_y
|
||||||
|
+ m_face.height()
|
||||||
|
+ m_face.descender() // descender is negative
|
||||||
|
- glyph->bearingY;
|
||||||
|
|
||||||
|
m_x += glyph->ft_glyph->advance.x / double(1 << 16);
|
||||||
|
m_y += glyph->ft_glyph->advance.y / double(1 << 16);
|
||||||
|
|
||||||
|
glyph->startX = initialX;
|
||||||
|
glyph->endX = m_x;
|
||||||
|
|
||||||
|
processGlyph(*glyph);
|
||||||
|
|
||||||
|
m_face.cache().doneGlyph(glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prevGlyph = glyphIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FaceFT& m_face;
|
||||||
|
bool m_useKerning;
|
||||||
|
FT_UInt m_prevGlyph;
|
||||||
|
double m_x, m_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename FaceFT>
|
||||||
|
gfx::Rect calc_text_bounds(FaceFT& face, const std::string& str) {
|
||||||
|
gfx::Rect bounds(0, 0, 0, 0);
|
||||||
|
auto it = base::utf8_const_iterator(str.begin());
|
||||||
|
auto end = base::utf8_const_iterator(str.end());
|
||||||
|
ForEachGlyph<FaceFT> feg(face);
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
feg.processChar(
|
||||||
|
*it,
|
||||||
|
[&bounds](typename FaceFT::Glyph& glyph) {
|
||||||
|
bounds |= gfx::Rect(int(glyph.x),
|
||||||
|
int(glyph.y),
|
||||||
|
glyph.bitmap->width,
|
||||||
|
glyph.bitmap->rows);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ft
|
||||||
|
|
||||||
|
#endif
|
@ -10,9 +10,7 @@
|
|||||||
|
|
||||||
#include "base/debug.h"
|
#include "base/debug.h"
|
||||||
#include "base/disable_copying.h"
|
#include "base/disable_copying.h"
|
||||||
#include "base/string.h"
|
|
||||||
#include "ft/freetype_headers.h"
|
#include "ft/freetype_headers.h"
|
||||||
#include "gfx/rect.h"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -33,6 +31,8 @@ namespace ft {
|
|||||||
template<typename Cache>
|
template<typename Cache>
|
||||||
class FaceFT {
|
class FaceFT {
|
||||||
public:
|
public:
|
||||||
|
typedef ft::Glyph Glyph;
|
||||||
|
|
||||||
FaceFT(FT_Face face) : m_face(face) {
|
FaceFT(FT_Face face) : m_face(face) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,79 +94,6 @@ namespace ft {
|
|||||||
DISABLE_COPYING(FaceFT);
|
DISABLE_COPYING(FaceFT);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FaceFT>
|
|
||||||
class ForEachGlyph {
|
|
||||||
public:
|
|
||||||
ForEachGlyph(FaceFT& face)
|
|
||||||
: m_face(face)
|
|
||||||
, m_useKerning(FT_HAS_KERNING((FT_Face)face) ? true: false)
|
|
||||||
, m_prevGlyph(0)
|
|
||||||
, m_x(0.0), m_y(0.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ProcessGlyph>
|
|
||||||
void processChar(const int chr, ProcessGlyph processGlyph) {
|
|
||||||
FT_UInt glyphIndex = m_face.cache().getGlyphIndex(m_face, chr);
|
|
||||||
double initialX = m_x;
|
|
||||||
|
|
||||||
if (m_useKerning && m_prevGlyph && glyphIndex) {
|
|
||||||
FT_Vector kerning;
|
|
||||||
FT_Get_Kerning(m_face, m_prevGlyph, glyphIndex,
|
|
||||||
FT_KERNING_DEFAULT, &kerning);
|
|
||||||
m_x += kerning.x / 64.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Glyph* glyph = m_face.cache().loadGlyph(
|
|
||||||
m_face, glyphIndex, m_face.antialias());
|
|
||||||
if (glyph) {
|
|
||||||
glyph->bitmap = &FT_BitmapGlyph(glyph->ft_glyph)->bitmap;
|
|
||||||
glyph->x = m_x + glyph->bearingX;
|
|
||||||
glyph->y = m_y
|
|
||||||
+ m_face.height()
|
|
||||||
+ m_face.descender() // descender is negative
|
|
||||||
- glyph->bearingY;
|
|
||||||
|
|
||||||
m_x += glyph->ft_glyph->advance.x / double(1 << 16);
|
|
||||||
m_y += glyph->ft_glyph->advance.y / double(1 << 16);
|
|
||||||
|
|
||||||
glyph->startX = initialX;
|
|
||||||
glyph->endX = m_x;
|
|
||||||
|
|
||||||
processGlyph(*glyph);
|
|
||||||
|
|
||||||
m_face.cache().doneGlyph(glyph);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_prevGlyph = glyphIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FaceFT& m_face;
|
|
||||||
bool m_useKerning;
|
|
||||||
FT_UInt m_prevGlyph;
|
|
||||||
double m_x, m_y;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FaceFT>
|
|
||||||
gfx::Rect calc_text_bounds(FaceFT& face, const std::string& str) {
|
|
||||||
gfx::Rect bounds(0, 0, 0, 0);
|
|
||||||
auto it = base::utf8_const_iterator(str.begin());
|
|
||||||
auto end = base::utf8_const_iterator(str.end());
|
|
||||||
ForEachGlyph<FaceFT> feg(face);
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
feg.processChar(
|
|
||||||
*it,
|
|
||||||
[&bounds](Glyph& glyph) {
|
|
||||||
bounds |= gfx::Rect(int(glyph.x),
|
|
||||||
int(glyph.y),
|
|
||||||
glyph.bitmap->width,
|
|
||||||
glyph.bitmap->rows);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoCache {
|
class NoCache {
|
||||||
public:
|
public:
|
||||||
void invalidate() {
|
void invalidate() {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "she/common/freetype_font.h"
|
#include "she/common/freetype_font.h"
|
||||||
|
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
|
#include "ft/algorithm.h"
|
||||||
#include "gfx/point.h"
|
#include "gfx/point.h"
|
||||||
#include "gfx/size.h"
|
#include "gfx/size.h"
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ namespace she {
|
|||||||
|
|
||||||
class FreeTypeFont : public Font {
|
class FreeTypeFont : public Font {
|
||||||
public:
|
public:
|
||||||
|
typedef ft::Face Face;
|
||||||
|
|
||||||
FreeTypeFont(const char* filename, int height);
|
FreeTypeFont(const char* filename, int height);
|
||||||
~FreeTypeFont();
|
~FreeTypeFont();
|
||||||
|
|
||||||
@ -29,11 +31,11 @@ namespace she {
|
|||||||
void setSize(int size) override;
|
void setSize(int size) override;
|
||||||
void setAntialias(bool antialias) override;
|
void setAntialias(bool antialias) override;
|
||||||
|
|
||||||
ft::Face& face() { return m_face; }
|
Face& face() { return m_face; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable ft::Lib m_ft;
|
mutable ft::Lib m_ft;
|
||||||
mutable ft::Face m_face;
|
mutable Face m_face;
|
||||||
};
|
};
|
||||||
|
|
||||||
FreeTypeFont* loadFreeTypeFont(const char* filename, int height);
|
FreeTypeFont* loadFreeTypeFont(const char* filename, int height);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "she/draw_text.h"
|
#include "she/draw_text.h"
|
||||||
|
|
||||||
|
#include "ft/algorithm.h"
|
||||||
#include "gfx/clip.h"
|
#include "gfx/clip.h"
|
||||||
#include "she/common/freetype_font.h"
|
#include "she/common/freetype_font.h"
|
||||||
#include "she/common/generic_surface.h"
|
#include "she/common/generic_surface.h"
|
||||||
@ -76,7 +77,7 @@ gfx::Rect draw_text(Surface* surface, Font* font,
|
|||||||
surface->getFormat(&fd);
|
surface->getFormat(&fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
ft::ForEachGlyph<ft::Face> feg(ttFont->face());
|
ft::ForEachGlyph<FreeTypeFont::Face> feg(ttFont->face());
|
||||||
while (it != end) {
|
while (it != end) {
|
||||||
int chr = *it;
|
int chr = *it;
|
||||||
if (delegate)
|
if (delegate)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user