mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-28 16:20:50 +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/image.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "ft/algorithm.h"
|
||||
#include "ft/face.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
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Aseprite FreeType Wrapper
|
||||
*Copyright (C) 2016 David Capello*
|
||||
*Copyright (C) 2016-2017 David Capello*
|
||||
|
||||
> 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/disable_copying.h"
|
||||
#include "base/string.h"
|
||||
#include "ft/freetype_headers.h"
|
||||
#include "gfx/rect.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -33,6 +31,8 @@ namespace ft {
|
||||
template<typename Cache>
|
||||
class FaceFT {
|
||||
public:
|
||||
typedef ft::Glyph Glyph;
|
||||
|
||||
FaceFT(FT_Face face) : m_face(face) {
|
||||
}
|
||||
|
||||
@ -94,79 +94,6 @@ namespace ft {
|
||||
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 {
|
||||
public:
|
||||
void invalidate() {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "she/common/freetype_font.h"
|
||||
|
||||
#include "base/string.h"
|
||||
#include "ft/algorithm.h"
|
||||
#include "gfx/point.h"
|
||||
#include "gfx/size.h"
|
||||
|
||||
|
@ -17,6 +17,8 @@ namespace she {
|
||||
|
||||
class FreeTypeFont : public Font {
|
||||
public:
|
||||
typedef ft::Face Face;
|
||||
|
||||
FreeTypeFont(const char* filename, int height);
|
||||
~FreeTypeFont();
|
||||
|
||||
@ -29,11 +31,11 @@ namespace she {
|
||||
void setSize(int size) override;
|
||||
void setAntialias(bool antialias) override;
|
||||
|
||||
ft::Face& face() { return m_face; }
|
||||
Face& face() { return m_face; }
|
||||
|
||||
private:
|
||||
mutable ft::Lib m_ft;
|
||||
mutable ft::Face m_face;
|
||||
mutable Face m_face;
|
||||
};
|
||||
|
||||
FreeTypeFont* loadFreeTypeFont(const char* filename, int height);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "she/draw_text.h"
|
||||
|
||||
#include "ft/algorithm.h"
|
||||
#include "gfx/clip.h"
|
||||
#include "she/common/freetype_font.h"
|
||||
#include "she/common/generic_surface.h"
|
||||
@ -76,7 +77,7 @@ gfx::Rect draw_text(Surface* surface, Font* font,
|
||||
surface->getFormat(&fd);
|
||||
}
|
||||
|
||||
ft::ForEachGlyph<ft::Face> feg(ttFont->face());
|
||||
ft::ForEachGlyph<FreeTypeFont::Face> feg(ttFont->face());
|
||||
while (it != end) {
|
||||
int chr = *it;
|
||||
if (delegate)
|
||||
|
Loading…
x
Reference in New Issue
Block a user