Merge branch 'unicode-text'

# Conflicts:
#	third_party/libpng
#	third_party/zlib
This commit is contained in:
David Capello 2016-04-04 10:26:57 -03:00
commit 8028cf64db
43 changed files with 1032 additions and 620 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 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
@ -33,7 +33,6 @@
#include "doc/palette.h"
#include "gfx/border.h"
#include "gfx/region.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/button.h"
@ -457,8 +456,7 @@ she::Surface* BrushPopup::createSurfaceForBrush(const BrushRef& origBrush)
delete palette;
}
else {
she::ScopedSurfaceLock lock(surface);
lock->clear();
surface->clear();
}
return surface;

View File

@ -360,7 +360,7 @@ void FileList::onPaint(ui::PaintEvent& ev)
if (fi->isFolder()) {
int icon_w = font()->textLength("[+]");
g->drawUIString("[+]", fgcolor, bgcolor, gfx::Point(x, y+2*guiscale()));
g->drawString("[+]", fgcolor, bgcolor, gfx::Point(x, y+2*guiscale()));
x += icon_w+2*guiscale();
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 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
@ -33,7 +33,6 @@
#include "gfx/rect.h"
#include "gfx/size.h"
#include "she/font.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/intern.h"
@ -504,9 +503,9 @@ she::Surface* SkinTheme::sliceSheet(she::Surface* sur, const gfx::Rect& bounds)
sur = she::instance()->createRgbaSurface(bounds.w, bounds.h);
{
she::ScopedSurfaceLock src(m_sheet);
she::ScopedSurfaceLock dst(sur);
src->blitTo(dst, bounds.x, bounds.y, 0, 0, bounds.w, bounds.h);
she::SurfaceLock lockSrc(m_sheet);
she::SurfaceLock lockDst(sur);
m_sheet->blitTo(sur, bounds.x, bounds.y, 0, 0, bounds.w, bounds.h);
}
sur->applyScale(guiscale());
@ -959,7 +958,7 @@ void SkinTheme::paintEntry(PaintEvent& ev)
}
w = g->measureChar(ch).w;
if (x+w > bounds.x2()-widget->childSpacing()*guiscale())
if (x+w > bounds.x2())
return;
caret_x = x;
@ -2017,7 +2016,7 @@ she::Font* SkinTheme::loadFont(const std::string& userFont, const std::string& t
// Try to load the font
while (rf.next()) {
try {
she::Font* f = she::instance()->loadBitmapFont(rf.filename().c_str(), guiscale());
she::Font* f = she::instance()->loadSpriteSheetFont(rf.filename().c_str(), guiscale());
if (f->isScalable())
f->setSize(8);
return f;

View File

@ -17,7 +17,6 @@
#include "app/ui/skin/skin_theme.h"
#include "app/ui/skin/style.h"
#include "she/font.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/intern.h"
@ -918,11 +917,11 @@ void Tabs::createFloatingOverlay(Tab* tab)
// Fill the surface with pink color
{
she::ScopedSurfaceLock lock(surface);
she::SurfaceLock lock(surface);
#ifdef USE_ALLEG4_BACKEND
lock->fillRect(gfx::rgba(255, 0, 255), gfx::Rect(0, 0, surface->width(), surface->height()));
surface->fillRect(gfx::rgba(255, 0, 255), gfx::Rect(0, 0, surface->width(), surface->height()));
#else
lock->fillRect(gfx::rgba(0, 0, 0, 0), gfx::Rect(0, 0, surface->width(), surface->height()));
surface->fillRect(gfx::rgba(0, 0, 0, 0), gfx::Rect(0, 0, surface->width(), surface->height()));
#endif
}
{
@ -933,16 +932,16 @@ void Tabs::createFloatingOverlay(Tab* tab)
#ifdef USE_ALLEG4_BACKEND
// Make pink parts transparent (TODO remove this hack when we change the back-end to Skia)
{
she::ScopedSurfaceLock lock(surface);
she::SurfaceLock lock(surface);
for (int y=0; y<surface->height(); ++y)
for (int x=0; x<surface->width(); ++x) {
gfx::Color c = lock->getPixel(x, y);
gfx::Color c = surface->getPixel(x, y);
c = (c != gfx::rgba(255, 0, 255, 0) &&
c != gfx::rgba(255, 0, 255, 255) ?
gfx::rgba(gfx::getr(c), gfx::getg(c), gfx::getb(c), 255):
gfx::ColorNone);
lock->putPixel(c, x, y);
surface->putPixel(c, x, y);
}
}
#endif

View File

@ -11,131 +11,52 @@
#include "app/util/freetype_utils.h"
#include "base/string.h"
#include "base/unique_ptr.h"
#include "doc/blend_funcs.h"
#include "doc/blend_internals.h"
#include "doc/color.h"
#include "doc/image.h"
#include "doc/primitives.h"
#include "ft/face.h"
#include "ft/lib.h"
#include <stdexcept>
#include "freetype/ftglyph.h"
#include "ft2build.h"
#include FT_FREETYPE_H
namespace app {
template<typename Iterator, typename Func>
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);
// 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 |
(antialias ? FT_LOAD_TARGET_NORMAL:
FT_LOAD_TARGET_MONO));
if (!err) {
callback(x, face->glyph);
x += face->glyph->advance.x >> 6;
}
prev_glyph = glyph_index;
}
}
class ScopedFTLib {
public:
ScopedFTLib(FT_Library& ft) : m_ft(ft) {
FT_Init_FreeType(&m_ft);
}
~ScopedFTLib() {
FT_Done_FreeType(m_ft);
}
private:
FT_Library& m_ft;
};
class ScopedFTFace {
public:
ScopedFTFace(FT_Face& face) : m_face(face) {
}
~ScopedFTFace() {
FT_Done_Face(m_face);
}
private:
FT_Face& m_face;
};
doc::Image* render_text(const std::string& fontfile, int fontsize,
const std::string& text,
doc::color_t color,
bool antialias)
{
base::UniquePtr<doc::Image> image(nullptr);
FT_Library ft;
ScopedFTLib init_and_done_ft(ft);
FT_Open_Args args;
memset(&args, 0, sizeof(args));
args.flags = FT_OPEN_PATHNAME;
args.pathname = (FT_String*)fontfile.c_str();
FT_Face face;
FT_Error err = FT_Open_Face(ft, &args, 0, &face);
if (!err) {
ScopedFTFace done_face(face);
ft::Lib ft;
ft::Face face(ft.open(fontfile));
if (face.isValid()) {
// Set font size
FT_Set_Pixel_Sizes(face, fontsize, fontsize);
face.setSize(fontsize);
face.setAntialias(antialias);
// Calculate text size
base::utf8_const_iterator begin(text.begin()), end(text.end());
gfx::Rect bounds(0, 0, 0, 0);
for_each_glyph(
face, antialias, 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);
});
gfx::Rect bounds = face.calcTextBounds(text);
// Render the image and copy it to the clipboard
if (!bounds.isEmpty()) {
image.reset(doc::Image::create(doc::IMAGE_RGB, bounds.w, bounds.h));
doc::clear_image(image, 0);
for_each_glyph(
face, antialias, begin, end,
[&bounds, &image, color, antialias](int x, FT_GlyphSlot glyph) {
int t, yimg = - bounds.y - glyph->bitmap_top;
face.forEachGlyph(
text,
[&bounds, &image, color, antialias](const ft::Glyph& glyph) {
int t, yimg = - bounds.y + int(glyph.y);
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 v=0; v<int(glyph.bitmap->rows); ++v, ++yimg) {
const uint8_t* p = glyph.bitmap->buffer + v*glyph.bitmap->pitch;
int ximg = - bounds.x + int(glyph.x);
int bit = 0;
for (int u=0; u<(int)glyph->bitmap.width; ++u, ++ximg) {
for (int u=0; u<int(glyph.bitmap->width); ++u, ++ximg) {
int alpha;
if (antialias) {

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -18,7 +18,6 @@
#include "doc/rgbmap.h"
#include "she/surface.h"
#include "she/surface_format.h"
#include "she/scoped_surface_lock.h"
#include <stdexcept>
@ -71,7 +70,7 @@ uint32_t convert_color_to_surface<BitmapTraits, she::kRgbaSurfaceFormat>(color_t
}
template<typename ImageTraits, typename AddressType>
void convert_image_to_surface_templ(const Image* image, she::LockedSurface* dst,
void convert_image_to_surface_templ(const Image* image, she::Surface* dst,
int src_x, int src_y, int dst_x, int dst_y, int w, int h, const Palette* palette, const she::SurfaceFormatData* fd)
{
const LockImageBits<ImageTraits> bits(image, gfx::Rect(src_x, src_y, w, h));
@ -105,7 +104,7 @@ struct Address24bpp
};
template<typename ImageTraits>
void convert_image_to_surface_selector(const Image* image, she::LockedSurface* surface,
void convert_image_to_surface_selector(const Image* image, she::Surface* surface,
int src_x, int src_y, int dst_x, int dst_y, int w, int h, const Palette* palette, const she::SurfaceFormatData* fd)
{
switch (fd->bitsPerPixel) {
@ -156,26 +155,26 @@ void convert_image_to_surface(const Image* image, const Palette* palette,
w = dstBounds.w;
h = dstBounds.h;
she::ScopedSurfaceLock dst(surface);
she::SurfaceLock lockDst(surface);
she::SurfaceFormatData fd;
dst->getFormat(&fd);
surface->getFormat(&fd);
switch (image->pixelFormat()) {
case IMAGE_RGB:
convert_image_to_surface_selector<RgbTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
convert_image_to_surface_selector<RgbTraits>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
break;
case IMAGE_GRAYSCALE:
convert_image_to_surface_selector<GrayscaleTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
convert_image_to_surface_selector<GrayscaleTraits>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
break;
case IMAGE_INDEXED:
convert_image_to_surface_selector<IndexedTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
convert_image_to_surface_selector<IndexedTraits>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
break;
case IMAGE_BITMAP:
convert_image_to_surface_selector<BitmapTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
convert_image_to_surface_selector<BitmapTraits>(image, surface, src_x, src_y, dst_x, dst_y, w, h, palette, &fd);
break;
default:

20
src/ft/LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2016 David Capello
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4
src/ft/README.md Normal file
View File

@ -0,0 +1,4 @@
# Aseprite FreeType Wrapper
*Copyright (C) 2016 David Capello*
> Distributed under [MIT license](LICENSE.txt)

257
src/ft/face.h Normal file
View File

@ -0,0 +1,257 @@
// Aseprite FreeType Wrapper
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef FT_FACE_H_INCLUDED
#define FT_FACE_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
#include "base/string.h"
#include "ft/freetype_headers.h"
#include "gfx/rect.h"
#include <map>
namespace ft {
struct Glyph {
FT_UInt glyph_index;
FT_Glyph ft_glyph;
FT_Bitmap* bitmap;
double bearingX;
double bearingY;
double x;
double y;
};
template<typename Cache>
class FaceBase {
public:
FaceBase(FT_Face face) : m_face(face) {
}
~FaceBase() {
if (m_face)
FT_Done_Face(m_face);
}
operator FT_Face() { return m_face; }
FT_Face operator->() { return m_face; }
bool isValid() const {
return (m_face != nullptr);
}
bool antialias() const {
return m_antialias;
}
void setAntialias(bool antialias) {
m_antialias = antialias;
m_cache.invalidate();
}
void setSize(int size) {
FT_Set_Pixel_Sizes(m_face, size, size);
m_cache.invalidate();
}
double height() const {
FT_Size_Metrics* metrics = &m_face->size->metrics;
double em_size = 1.0 * m_face->units_per_EM;
double y_scale = metrics->y_ppem / em_size;
return int(m_face->height * y_scale) - 1;
}
double ascender() const {
FT_Size_Metrics* metrics = &m_face->size->metrics;
double em_size = 1.0 * m_face->units_per_EM;
double y_scale = metrics->y_ppem / em_size;
return int(m_face->ascender * y_scale);
}
double descender() const {
FT_Size_Metrics* metrics = &m_face->size->metrics;
double em_size = 1.0 * m_face->units_per_EM;
double y_scale = metrics->y_ppem / em_size;
return int(m_face->descender * y_scale);
}
protected:
FT_Face m_face;
bool m_antialias;
Cache m_cache;
private:
DISABLE_COPYING(FaceBase);
};
template<typename Cache>
class FaceFT : public FaceBase<Cache> {
public:
using FaceBase<Cache>::m_face;
using FaceBase<Cache>::m_cache;
FaceFT(FT_Face face)
: FaceBase<Cache>(face) {
}
template<typename Callback>
void forEachGlyph(const std::string& str, Callback callback) {
bool use_kerning = (FT_HAS_KERNING(this->m_face) ? true: false);
FT_UInt prev_glyph = 0;
double x = 0, y = 0;
auto it = base::utf8_const_iterator(str.begin());
auto end = base::utf8_const_iterator(str.end());
for (; it != end; ++it) {
FT_UInt glyph_index = this->m_cache.getGlyphIndex(
this->m_face, *it);
if (use_kerning && prev_glyph && glyph_index) {
FT_Vector kerning;
FT_Get_Kerning(this->m_face, prev_glyph, glyph_index,
FT_KERNING_DEFAULT, &kerning);
x += kerning.x / 64.0;
}
Glyph* glyph = this->m_cache.loadGlyph(
this->m_face, glyph_index, this->m_antialias);
if (glyph) {
glyph->bitmap = &FT_BitmapGlyph(glyph->ft_glyph)->bitmap;
glyph->x = x + glyph->bearingX;
glyph->y = y
+ this->height()
+ this->descender() // descender is negative
- glyph->bearingY;
callback(*glyph);
x += glyph->ft_glyph->advance.x / double(1 << 16);
y += glyph->ft_glyph->advance.y / double(1 << 16);
this->m_cache.doneGlyph(glyph);
}
prev_glyph = glyph_index;
}
}
gfx::Rect calcTextBounds(const std::string& str) {
gfx::Rect bounds(0, 0, 0, 0);
forEachGlyph(
str,
[&bounds, this](Glyph& glyph) {
bounds |= gfx::Rect(int(glyph.x),
int(glyph.y),
glyph.bitmap->width,
glyph.bitmap->rows);
});
return bounds;
}
};
class NoCache {
public:
void invalidate() {
// Do nothing
}
FT_UInt getGlyphIndex(FT_Face face, int charCode) {
return FT_Get_Char_Index(face, charCode);
}
Glyph* loadGlyph(FT_Face face, FT_UInt glyphIndex, bool antialias) {
FT_Error err = FT_Load_Glyph(
face, glyphIndex,
FT_LOAD_RENDER |
(antialias ? FT_LOAD_TARGET_NORMAL:
FT_LOAD_TARGET_MONO));
if (err)
return nullptr;
FT_Glyph ft_glyph;
err = FT_Get_Glyph(face->glyph, &ft_glyph);
if (err)
return nullptr;
if (ft_glyph->format != FT_GLYPH_FORMAT_BITMAP) {
err = FT_Glyph_To_Bitmap(&ft_glyph, FT_RENDER_MODE_NORMAL, 0, 1);
if (!err) {
FT_Done_Glyph(ft_glyph);
return nullptr;
}
}
m_glyph.ft_glyph = ft_glyph;
m_glyph.bearingX = face->glyph->metrics.horiBearingX / 64.0;
m_glyph.bearingY = face->glyph->metrics.horiBearingY / 64.0;
return &m_glyph;
}
void doneGlyph(Glyph* glyph) {
ASSERT(glyph);
FT_Done_Glyph(glyph->ft_glyph);
}
private:
Glyph m_glyph;
};
class SimpleCache : public NoCache {
public:
~SimpleCache() {
invalidate();
}
void invalidate() {
for (auto& it : m_glyphMap) {
FT_Done_Glyph(it.second->ft_glyph);
delete it.second;
}
m_glyphMap.clear();
}
Glyph* loadGlyph(FT_Face face, FT_UInt glyphIndex, bool antialias) {
auto it = m_glyphMap.find(glyphIndex);
if (it != m_glyphMap.end())
return it->second;
Glyph* glyph = NoCache::loadGlyph(face, glyphIndex, antialias);
if (!glyph)
return nullptr;
FT_Glyph new_ft_glyph = nullptr;
FT_Glyph_Copy(glyph->ft_glyph, &new_ft_glyph);
if (!new_ft_glyph)
return nullptr;
Glyph* newGlyph = new Glyph(*glyph);
newGlyph->ft_glyph = new_ft_glyph;
m_glyphMap[glyphIndex] = newGlyph;
FT_Done_Glyph(glyph->ft_glyph);
return newGlyph;
}
void doneGlyph(Glyph* glyph) {
// Do nothing
}
private:
std::map<FT_UInt, Glyph*> m_glyphMap;
};
typedef FaceFT<SimpleCache> Face;
} // namespace ft
#endif

15
src/ft/freetype_headers.h Normal file
View File

@ -0,0 +1,15 @@
// Aseprite FreeType Wrapper
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef FT_FREETYPE_HEADERS_H_INCLUDED
#define FT_FREETYPE_HEADERS_H_INCLUDED
#pragma once
#include "freetype/ftglyph.h"
#include "ft2build.h"
#include FT_FREETYPE_H
#endif

54
src/ft/lib.h Normal file
View File

@ -0,0 +1,54 @@
// Aseprite FreeType Wrapper
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef FT_LIB_H_INCLUDED
#define FT_LIB_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
#include "ft/freetype_headers.h"
#include <string>
namespace ft {
class Lib {
public:
Lib() : m_ft(nullptr) {
FT_Init_FreeType(&m_ft);
}
~Lib() {
if (m_ft)
FT_Done_FreeType(m_ft);
}
operator FT_Library() {
return m_ft;
}
FT_Face open(const std::string& filename) {
FT_Open_Args args;
memset(&args, 0, sizeof(args));
args.flags = FT_OPEN_PATHNAME;
args.pathname = (FT_String*)filename.c_str();
FT_Face face = nullptr;
FT_Error err = FT_Open_Face(m_ft, &args, 0, &face);
if (!err)
FT_Select_Charmap(face, FT_ENCODING_UNICODE);
return face;
}
private:
FT_Library m_ft;
DISABLE_COPYING(Lib);
};
} // namespace ft
#endif

View File

@ -1,7 +1,8 @@
# SHE
# Copyright (C) 2012-2016 David Capello
set(SHE_SOURCES)
set(SHE_SOURCES
common/freetype_font.cpp)
######################################################################
# Allegro 4 backend
@ -225,7 +226,8 @@ add_library(she ${SHE_SOURCES})
target_link_libraries(she
gfx-lib
base-lib)
base-lib
${FREETYPE_LIBRARY})
if(USE_ALLEG4_BACKEND)
target_link_libraries(she

View File

@ -477,9 +477,9 @@ void Alleg4Display::recreateSurface()
m_surface = newSurface;
}
NonDisposableSurface* Alleg4Display::getSurface()
Surface* Alleg4Display::getSurface()
{
return static_cast<NonDisposableSurface*>(m_surface);
return m_surface;
}
void Alleg4Display::flip(const gfx::Rect& bounds)

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -27,7 +27,7 @@ namespace she {
int scale() const override;
void setScale(int scale) override;
void recreateSurface();
NonDisposableSurface* getSurface() override;
Surface* getSurface() override;
void flip(const gfx::Rect& bounds) override;
void maximize() override;
bool isMaximized() const override;

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -80,23 +80,27 @@ inline gfx::Color from_allegro(int color_depth, int color)
Alleg4Surface::Alleg4Surface(BITMAP* bmp, DestroyFlag destroy)
: m_bmp(bmp)
, m_destroy(destroy)
, m_lock(0)
{
}
Alleg4Surface::Alleg4Surface(int width, int height, DestroyFlag destroy)
: m_bmp(create_bitmap(width, height))
, m_destroy(destroy)
, m_lock(0)
{
}
Alleg4Surface::Alleg4Surface(int width, int height, int bpp, DestroyFlag destroy)
: m_bmp(create_bitmap_ex(bpp, width, height))
, m_destroy(destroy)
, m_lock(0)
{
}
Alleg4Surface::~Alleg4Surface()
{
ASSERT(m_lock == 0);
if (m_destroy & DestroyHandle) {
if (m_bmp)
destroy_bitmap(m_bmp);
@ -157,10 +161,18 @@ bool Alleg4Surface::intersectClipRect(const gfx::Rect& rc)
m_bmp->ct < m_bmp->cb);
}
LockedSurface* Alleg4Surface::lock()
void Alleg4Surface::lock()
{
acquire_bitmap(m_bmp);
return this;
ASSERT(m_lock >= 0);
if (m_lock++ == 0)
acquire_bitmap(m_bmp);
}
void Alleg4Surface::unlock()
{
ASSERT(m_lock > 0);
if (--m_lock == 0)
release_bitmap(m_bmp);
}
void Alleg4Surface::setDrawMode(DrawMode mode, int param)
@ -198,23 +210,6 @@ void* Alleg4Surface::nativeHandle()
return reinterpret_cast<void*>(m_bmp);
}
// LockedSurface implementation
int Alleg4Surface::lockedWidth() const
{
return m_bmp->w;
}
int Alleg4Surface::lockedHeight() const
{
return m_bmp->h;
}
void Alleg4Surface::unlock()
{
release_bitmap(m_bmp);
}
void Alleg4Surface::clear()
{
clear_to_color(m_bmp, 0);
@ -358,7 +353,7 @@ void Alleg4Surface::fillRect(gfx::Color color, const gfx::Rect& rc)
solid_mode();
}
void Alleg4Surface::blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const
void Alleg4Surface::blitTo(Surface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const
{
ASSERT(m_bmp);
ASSERT(dest);
@ -379,12 +374,12 @@ void Alleg4Surface::scrollTo(const gfx::Rect& rc, int dx, int dy)
rc.w, rc.h);
}
void Alleg4Surface::drawSurface(const LockedSurface* src, int dstx, int dsty)
void Alleg4Surface::drawSurface(const Surface* src, int dstx, int dsty)
{
draw_sprite(m_bmp, static_cast<const Alleg4Surface*>(src)->m_bmp, dstx, dsty);
}
void Alleg4Surface::drawRgbaSurface(const LockedSurface* src, int dstx, int dsty)
void Alleg4Surface::drawRgbaSurface(const Surface* src, int dstx, int dsty)
{
set_alpha_blender();
draw_trans_sprite(m_bmp, static_cast<const Alleg4Surface*>(src)->m_bmp, dstx, dsty);

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -11,12 +11,11 @@
#include <allegro.h>
#include "she/surface.h"
#include "she/common/locked_surface.h"
#include "she/common/generic_surface.h"
namespace she {
class Alleg4Surface : public Surface
, public CommonLockedSurface {
class Alleg4Surface : public GenericDrawTextSurface<GenericDrawColoredRgbaSurface<Surface> > {
public:
enum DestroyFlag {
None = 0,
@ -38,15 +37,11 @@ namespace she {
gfx::Rect getClipBounds() override;
void setClipBounds(const gfx::Rect& rc) override;
bool intersectClipRect(const gfx::Rect& rc) override;
LockedSurface* lock() override;
void lock() override;
void unlock() override;
void setDrawMode(DrawMode mode, int param) override;
void applyScale(int scale) override;
void* nativeHandle() override;
// LockedSurface implementation
int lockedWidth() const override;
int lockedHeight() const override;
void unlock() override;
void clear() override;
uint8_t* getData(int x, int y) const override;
void getFormat(SurfaceFormatData* formatData) const override;
@ -57,14 +52,15 @@ namespace she {
void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b) override;
void drawRect(gfx::Color color, const gfx::Rect& rc) override;
void fillRect(gfx::Color color, const gfx::Rect& rc) override;
void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override;
void blitTo(Surface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override;
void scrollTo(const gfx::Rect& rc, int dx, int dy) override;
void drawSurface(const LockedSurface* src, int dstx, int dsty) override;
void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) override;
void drawSurface(const Surface* src, int dstx, int dsty) override;
void drawRgbaSurface(const Surface* src, int dstx, int dsty) override;
private:
BITMAP* m_bmp;
DestroyFlag m_destroy;
int m_lock;
};
} // namespace she

View File

@ -0,0 +1,89 @@
// SHE library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "she/common/freetype_font.h"
#include "base/string.h"
#include "gfx/point.h"
#include "gfx/size.h"
namespace she {
FreeTypeFont::FreeTypeFont(const char* filename, int height)
: m_face(m_ft.open(filename))
{
ASSERT(m_face.isValid());
if (m_face.isValid())
m_face.setSize(height);
}
FreeTypeFont::~FreeTypeFont()
{
}
bool FreeTypeFont::isValid() const
{
return m_face.isValid();
}
void FreeTypeFont::dispose()
{
delete this;
}
FontType FreeTypeFont::type()
{
return FontType::kTrueType;
}
int FreeTypeFont::height() const
{
return int(m_face.height());
}
int FreeTypeFont::charWidth(int chr) const
{
// TODO avoid creating a temporary string
std::wstring tmp;
tmp.push_back(chr);
return m_face.calcTextBounds(base::to_utf8(tmp)).w;
}
int FreeTypeFont::textLength(const std::string& str) const
{
return m_face.calcTextBounds(str).w;
}
bool FreeTypeFont::isScalable() const
{
return true;
}
void FreeTypeFont::setSize(int size)
{
m_face.setSize(size);
}
void FreeTypeFont::setAntialias(bool antialias)
{
m_face.setAntialias(antialias);
}
FreeTypeFont* loadFreeTypeFont(const char* filename, int height)
{
FreeTypeFont* font = new FreeTypeFont(filename, height);
if (!font->isValid()) {
delete font;
font = nullptr;
}
return font;
}
} // namespace she

View File

@ -0,0 +1,44 @@
// SHE library
// Copyright (C) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_COMMON_FREETYPE_FONT_H_INCLUDED
#define SHE_COMMON_FREETYPE_FONT_H_INCLUDED
#pragma once
#include "ft/face.h"
#include "ft/lib.h"
#include "she/font.h"
namespace she {
class Font;
class FreeTypeFont : public Font {
public:
FreeTypeFont(const char* filename, int height);
~FreeTypeFont();
bool isValid() const;
void dispose() override;
FontType type() override;
int height() const override;
int charWidth(int chr) const override;
int textLength(const std::string& str) const override;
bool isScalable() const override;
void setSize(int size) override;
void setAntialias(bool antialias) override;
ft::Face& face() { return m_face; }
private:
mutable ft::Lib m_ft;
mutable ft::Face m_face;
};
FreeTypeFont* loadFreeTypeFont(const char* filename, int height);
} // namespace she
#endif

View File

@ -0,0 +1,236 @@
// SHE library
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_COMMON_GENERIC_SURFACE_H
#define SHE_COMMON_GENERIC_SURFACE_H
#pragma once
#include "gfx/clip.h"
#include "she/common/freetype_font.h"
#include "she/common/sprite_sheet_font.h"
namespace she {
namespace {
#define MUL_UN8(a, b, t) \
((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
gfx::Color blend(const gfx::Color backdrop, gfx::Color src)
{
if (gfx::geta(backdrop) == 0)
return src;
else if (gfx::geta(src) == 0)
return backdrop;
int Br, Bg, Bb, Ba;
int Sr, Sg, Sb, Sa;
int Rr, Rg, Rb, Ra;
Br = gfx::getr(backdrop);
Bg = gfx::getg(backdrop);
Bb = gfx::getb(backdrop);
Ba = gfx::geta(backdrop);
Sr = gfx::getr(src);
Sg = gfx::getg(src);
Sb = gfx::getb(src);
Sa = gfx::geta(src);
int t;
Ra = Ba + Sa - MUL_UN8(Ba, Sa, t);
Rr = Br + (Sr-Br) * Sa / Ra;
Rg = Bg + (Sg-Bg) * Sa / Ra;
Rb = Bb + (Sb-Bb) * Sa / Ra;
return gfx::rgba(Rr, Rg, Rb, Ra);
}
} // anoynmous namespace
template<typename Base>
class GenericDrawColoredRgbaSurface : public Base {
public:
void drawColoredRgbaSurface(const Surface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
gfx::Clip clip(clipbase);
if (!clip.clip(this->width(),
this->height(),
src->width(), src->height()))
return;
SurfaceFormatData format;
src->getFormat(&format);
ASSERT(format.format == kRgbaSurfaceFormat);
ASSERT(format.bitsPerPixel == 32);
for (int v=0; v<clip.size.h; ++v) {
const uint32_t* ptr = (const uint32_t*)src->getData(
clip.src.x, clip.src.y+v);
for (int u=0; u<clip.size.w; ++u) {
gfx::Color dstColor = this->getPixel(clip.dst.x+u, clip.dst.y+v);
if (gfx::geta(bg) > 0)
dstColor = blend(dstColor, bg);
uint32_t src = (((*ptr) & format.alphaMask) >> format.alphaShift);
if (src > 0) {
src = gfx::rgba(gfx::getr(fg),
gfx::getg(fg),
gfx::getb(fg), src);
dstColor = blend(dstColor, src);
}
this->putPixel(dstColor, clip.dst.x+u, clip.dst.y+v);
++ptr;
}
}
}
};
template<typename Base>
class GenericDrawTextSurface : public Base {
public:
void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) override {
switch (font->type()) {
case FontType::kSpriteSheet: {
SpriteSheetFont* ssFont = static_cast<SpriteSheetFont*>(font);
gfx::Rect charBounds = ssFont->getCharBounds(chr);
if (!charBounds.isEmpty()) {
Surface* sheet = ssFont->getSurfaceSheet();
SurfaceLock lock(sheet);
this->drawColoredRgbaSurface(sheet, fg, bg, gfx::Clip(x, y, charBounds));
}
break;
}
case FontType::kTrueType: {
// TODO avoid a temporary string
std::wstring str;
str.push_back(chr);
drawString(font, fg, bg, x, y, base::to_utf8(str).c_str());
break;
}
}
}
void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) override {
switch (font->type()) {
case FontType::kSpriteSheet: {
base::utf8_const_iterator it(str.begin()), end(str.end());
while (it != end) {
drawChar(font, fg, bg, x, y, *it);
x += font->charWidth(*it);
++it;
}
break;
}
case FontType::kTrueType: {
FreeTypeFont* ttFont = static_cast<FreeTypeFont*>(font);
bool antialias = ttFont->face().antialias();
int fg_alpha = gfx::geta(fg);
gfx::Rect clipBounds = this->getClipBounds();
she::SurfaceFormatData fd;
this->getFormat(&fd);
ttFont->face().forEachGlyph(
str,
[this, x, y, fg, fg_alpha, bg, antialias, &clipBounds, &fd](const ft::Glyph& glyph) {
gfx::Rect origDstBounds(x + int(glyph.x),
y + int(glyph.y),
int(glyph.bitmap->width),
int(glyph.bitmap->rows));
gfx::Rect dstBounds = origDstBounds;
dstBounds &= clipBounds;
if (dstBounds.isEmpty())
return;
int clippedRows = dstBounds.y - origDstBounds.y;
int dst_y = dstBounds.y;
int t;
for (int v=0; v<dstBounds.h; ++v, ++dst_y) {
int bit = 0;
const uint8_t* p = glyph.bitmap->buffer
+ (v+clippedRows)*glyph.bitmap->pitch;
int dst_x = dstBounds.x;
uint32_t* dst_address =
(uint32_t*)this->getData(dst_x, dst_y);
// Skip first clipped pixels
for (int u=0; u<dstBounds.x-origDstBounds.x; ++u) {
if (antialias) {
++p;
}
else {
if (bit == 8) {
bit = 0;
++p;
}
}
}
for (int u=0; u<dstBounds.w; ++u, ++dst_x) {
ASSERT(clipBounds.contains(gfx::Point(dst_x, dst_y)));
int alpha;
if (antialias) {
alpha = *(p++);
}
else {
alpha = ((*p) & (1 << (7 - (bit++))) ? 255: 0);
if (bit == 8) {
bit = 0;
++p;
}
}
uint32_t backdrop = *dst_address;
gfx::Color backdropColor =
gfx::rgba(
((backdrop & fd.redMask) >> fd.redShift),
((backdrop & fd.greenMask) >> fd.greenShift),
((backdrop & fd.blueMask) >> fd.blueShift),
((backdrop & fd.alphaMask) >> fd.alphaShift));
gfx::Color output = gfx::rgba(gfx::getr(fg),
gfx::getg(fg),
gfx::getb(fg),
MUL_UN8(fg_alpha, alpha, t));
if (gfx::geta(bg) > 0)
output = blend(blend(backdropColor, bg), output);
else
output = blend(backdropColor, output);
*dst_address =
((gfx::getr(output) << fd.redShift ) & fd.redMask ) |
((gfx::getg(output) << fd.greenShift) & fd.greenMask) |
((gfx::getb(output) << fd.blueShift ) & fd.blueMask ) |
((gfx::geta(output) << fd.alphaShift) & fd.alphaMask);
++dst_address;
}
}
});
break;
}
}
}
};
} // namespace she
#endif

View File

@ -1,115 +0,0 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_COMMON_LOCKED_SURFACE_H
#define SHE_COMMON_LOCKED_SURFACE_H
#pragma once
#include "gfx/clip.h"
#include "she/common/font.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
namespace she {
namespace {
#define MUL_UN8(a, b, t) \
((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
gfx::Color blend(const gfx::Color backdrop, gfx::Color src)
{
if (gfx::geta(backdrop) == 0)
return src;
else if (gfx::geta(src) == 0)
return backdrop;
int Br, Bg, Bb, Ba;
int Sr, Sg, Sb, Sa;
int Rr, Rg, Rb, Ra;
Br = gfx::getr(backdrop);
Bg = gfx::getg(backdrop);
Bb = gfx::getb(backdrop);
Ba = gfx::geta(backdrop);
Sr = gfx::getr(src);
Sg = gfx::getg(src);
Sb = gfx::getb(src);
Sa = gfx::geta(src);
int t;
Ra = Ba + Sa - MUL_UN8(Ba, Sa, t);
Rr = Br + (Sr-Br) * Sa / Ra;
Rg = Bg + (Sg-Bg) * Sa / Ra;
Rb = Bb + (Sb-Bb) * Sa / Ra;
return gfx::rgba(Rr, Rg, Rb, Ra);
}
} // anoynmous namespace
class CommonLockedSurface : public LockedSurface {
public:
void drawColoredRgbaSurface(const LockedSurface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
gfx::Clip clip(clipbase);
if (!clip.clip(lockedWidth(), lockedHeight(), src->lockedWidth(), src->lockedHeight()))
return;
SurfaceFormatData format;
src->getFormat(&format);
ASSERT(format.format == kRgbaSurfaceFormat);
ASSERT(format.bitsPerPixel == 32);
for (int v=0; v<clip.size.h; ++v) {
const uint32_t* ptr = (const uint32_t*)src->getData(
clip.src.x, clip.src.y+v);
for (int u=0; u<clip.size.w; ++u) {
gfx::Color dstColor = getPixel(clip.dst.x+u, clip.dst.y+v);
if (gfx::geta(bg) > 0)
dstColor = blend(dstColor, bg);
uint32_t src = (((*ptr) & format.alphaMask) >> format.alphaShift);
if (src > 0) {
src = gfx::rgba(gfx::getr(fg),
gfx::getg(fg),
gfx::getb(fg), src);
dstColor = blend(dstColor, src);
}
putPixel(dstColor, clip.dst.x+u, clip.dst.y+v);
++ptr;
}
}
}
void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) override {
CommonFont* commonFont = static_cast<CommonFont*>(font);
gfx::Rect charBounds = commonFont->getCharBounds(chr);
if (!charBounds.isEmpty()) {
ScopedSurfaceLock lock(commonFont->getSurfaceSheet());
drawColoredRgbaSurface(lock, fg, bg, gfx::Clip(x, y, charBounds));
}
}
void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) override {
base::utf8_const_iterator it(str.begin()), end(str.end());
while (it != end) {
drawChar(font, fg, bg, x, y, *it);
x += font->charWidth(*it);
++it;
}
}
};
} // namespace she
#endif

View File

@ -4,29 +4,27 @@
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_COMMON_FONT_H
#define SHE_COMMON_FONT_H
#ifndef SHE_SPRITE_SHEET_FONT_H
#define SHE_SPRITE_SHEET_FONT_H
#pragma once
#include "base/debug.h"
#include "base/string.h"
#include "gfx/rect.h"
#include "she/font.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include <vector>
namespace she {
class CommonFont : public Font {
class SpriteSheetFont : public Font {
public:
CommonFont() : m_sheet(nullptr) {
SpriteSheetFont() : m_sheet(nullptr) {
}
~CommonFont() {
~SpriteSheetFont() {
ASSERT(m_sheet);
m_sheet->dispose();
}
@ -35,6 +33,10 @@ public:
delete this;
}
FontType type() override {
return FontType::kSpriteSheet;
}
int height() const override {
return getCharBounds(' ').h;
}
@ -61,6 +63,10 @@ public:
// Do nothing
}
void setAntialias(bool antialias) override {
// Do nothing
}
Surface* getSurfaceSheet() const {
return m_sheet;
}
@ -74,13 +80,13 @@ public:
}
static Font* fromSurface(Surface* sur) {
CommonFont* font = new CommonFont;
SpriteSheetFont* font = new SpriteSheetFont;
font->m_sheet = sur;
ScopedSurfaceLock surLock(sur);
SurfaceLock lock(sur);
gfx::Rect bounds(0, 0, 1, 1);
while (font->findChar(surLock, sur->width(), sur->height(), bounds)) {
while (font->findChar(sur, sur->width(), sur->height(), bounds)) {
font->m_chars.push_back(bounds);
bounds.x += bounds.w;
}
@ -90,7 +96,7 @@ public:
private:
bool findChar(const LockedSurface* sur, int width, int height, gfx::Rect& bounds) {
bool findChar(const Surface* sur, int width, int height, gfx::Rect& bounds) {
gfx::Color keyColor = sur->getPixel(0, 0);
while (sur->getPixel(bounds.x, bounds.y) == keyColor) {

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -22,7 +22,8 @@
#include "she/native_dialogs.h"
#endif
#include "she/common/font.h"
#include "she/common/freetype_font.h"
#include "she/common/sprite_sheet_font.h"
namespace she {
@ -76,16 +77,20 @@ public:
#endif
}
Font* loadBitmapFont(const char* filename, int scale) override {
Font* loadSpriteSheetFont(const char* filename, int scale) override {
Surface* sheet = loadRgbaSurface(filename);
Font* font = nullptr;
if (sheet) {
sheet->applyScale(scale);
font = CommonFont::fromSurface(sheet);
font = SpriteSheetFont::fromSurface(sheet);
}
return font;
}
Font* loadTrueTypeFont(const char* filename, int height) override {
return loadFreeTypeFont(filename, height);
}
private:
NativeDialogs* m_nativeDialogs;
};

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -16,7 +16,6 @@
namespace she {
class NonDisposableSurface;
class Surface;
class Font;
@ -46,7 +45,7 @@ namespace she {
// Returns the main surface to draw into this display.
// You must not dispose this surface.
virtual NonDisposableSurface* getSurface() = 0;
virtual Surface* getSurface() = 0;
// Flips all graphics in the surface to the real display.
virtual void flip(const gfx::Rect& bounds) = 0;

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -12,15 +12,23 @@
namespace she {
enum class FontType {
kUnknown,
kSpriteSheet,
kTrueType,
};
class Font {
public:
virtual ~Font() { }
virtual void dispose() = 0;
virtual FontType type() = 0;
virtual int height() const = 0;
virtual int charWidth(int chr) const = 0;
virtual int textLength(const std::string& str) const = 0;
virtual bool isScalable() const = 0;
virtual void setSize(int size) = 0;
virtual void setAntialias(bool antialias) = 0;
};
} // namespace she

View File

@ -1,58 +0,0 @@
// SHE library
// Copyright (C) 2012-2013, 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_LOCKED_SURFACE_H_INCLUDED
#define SHE_LOCKED_SURFACE_H_INCLUDED
#pragma once
#include "gfx/color.h"
#include "gfx/fwd.h"
#include "she/surface_format.h"
#include <string>
namespace gfx {
class Clip;
}
namespace she {
class Font;
class LockedSurface {
public:
virtual ~LockedSurface() { }
virtual int lockedWidth() const = 0;
virtual int lockedHeight() const = 0;
virtual void unlock() = 0;
virtual void clear() = 0;
virtual uint8_t* getData(int x, int y) const = 0;
virtual void getFormat(SurfaceFormatData* formatData) const = 0;
virtual gfx::Color getPixel(int x, int y) const = 0;
virtual void putPixel(gfx::Color color, int x, int y) = 0;
virtual void drawHLine(gfx::Color color, int x, int y, int w) = 0;
virtual void drawVLine(gfx::Color color, int x, int y, int h) = 0;
virtual void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b) = 0;
virtual void drawRect(gfx::Color color, const gfx::Rect& rc) = 0;
virtual void fillRect(gfx::Color color, const gfx::Rect& rc) = 0;
virtual void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const = 0;
virtual void scrollTo(const gfx::Rect& rc, int dx, int dy) = 0;
virtual void drawSurface(const LockedSurface* src, int dstx, int dsty) = 0;
virtual void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) = 0;
virtual void drawColoredRgbaSurface(const LockedSurface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clip) = 0;
virtual void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) = 0;
virtual void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) = 0;
};
} // namespace she
#endif

View File

@ -1,29 +0,0 @@
// SHE library
// Copyright (C) 2012-2013 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_SCOPED_SURFACE_LOCK_H_INCLUDED
#define SHE_SCOPED_SURFACE_LOCK_H_INCLUDED
#pragma once
#include "she/surface.h"
#include "she/locked_surface.h"
namespace she {
class ScopedSurfaceLock {
public:
ScopedSurfaceLock(Surface* surface) : m_lock(surface->lock()) { }
~ScopedSurfaceLock() { m_lock->unlock(); }
LockedSurface* operator->() { return m_lock; }
operator LockedSurface*() { return m_lock; }
private:
LockedSurface* m_lock;
};
} // namespace she
#endif

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -14,9 +14,7 @@
#include "she/event.h"
#include "she/event_queue.h"
#include "she/font.h"
#include "she/locked_surface.h"
#include "she/scoped_handle.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -100,9 +100,9 @@ void SkiaDisplay::setScale(int scale)
m_window.setScale(scale);
}
NonDisposableSurface* SkiaDisplay::getSurface()
Surface* SkiaDisplay::getSurface()
{
return static_cast<NonDisposableSurface*>(m_surface);
return m_surface;
}
// Flips all graphics in the surface to the real display. Returns

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -39,7 +39,7 @@ public:
// Returns the main surface to draw into this display.
// You must not dispose this surface.
NonDisposableSurface* getSurface() override;
Surface* getSurface() override;
// Flips all graphics in the surface to the real display.
void flip(const gfx::Rect& bounds) override;

View File

@ -10,9 +10,8 @@
#include "base/exception.h"
#include "gfx/clip.h"
#include "she/common/font.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
#include "she/common/generic_surface.h"
#include "she/common/sprite_sheet_font.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
@ -32,17 +31,18 @@ inline SkIRect to_skia(const gfx::Rect& rc) {
return SkIRect::MakeXYWH(rc.x, rc.y, rc.w, rc.h);
}
class SkiaSurface : public NonDisposableSurface
, public LockedSurface {
class SkiaSurface : public GenericDrawTextSurface<Surface> {
public:
SkiaSurface() : m_surface(nullptr)
, m_canvas(nullptr) {
, m_canvas(nullptr)
, m_lock(0) {
}
SkiaSurface(SkSurface* surface)
: m_surface(surface)
, m_canvas(nullptr)
, m_clip(0, 0, width(), height())
, m_lock(0)
{
ASSERT(m_surface);
if (m_surface)
@ -50,6 +50,7 @@ public:
}
~SkiaSurface() {
ASSERT(m_lock == 0);
if (!m_surface)
delete m_canvas;
}
@ -160,9 +161,16 @@ public:
}
}
LockedSurface* lock() override {
m_bitmap.lockPixels();
return this;
void lock() override {
ASSERT(m_lock >= 0);
if (m_lock++ == 0)
m_bitmap.lockPixels();
}
void unlock() override {
ASSERT(m_lock > 0);
if (--m_lock == 0)
m_bitmap.unlockPixels();
}
void applyScale(int scaleFactor) override {
@ -191,20 +199,6 @@ public:
return (void*)this;
}
// LockedSurface impl
int lockedWidth() const override {
return width();
}
int lockedHeight() const override {
return height();
}
void unlock() override {
m_bitmap.unlockPixels();
}
void clear() override {
m_canvas->clear(0);
}
@ -329,11 +323,12 @@ public:
m_canvas->drawIRect(to_skia(rc), m_paint);
}
void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override {
void blitTo(Surface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override {
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
std::vector<uint32_t> pixels(width * height * 4);
m_canvas->readPixels(info, (void*)&pixels[0], 4*width, srcx, srcy);
((SkiaSurface*)dest)->m_canvas->writePixels(info, (void*)&pixels[0], 4*width, dstx, dsty);
static_cast<SkiaSurface*>(dest)
->m_canvas->writePixels(info, (void*)&pixels[0], 4*width, dstx, dsty);
}
void scrollTo(const gfx::Rect& rc, int dx, int dy) override {
@ -344,6 +339,7 @@ public:
return;
if (m_surface) {
SurfaceLock lock(this);
blitTo(this, clip.src.x, clip.src.y, clip.dst.x, clip.dst.y, clip.size.w, clip.size.h);
return;
}
@ -374,7 +370,7 @@ public:
}
}
void drawSurface(const LockedSurface* src, int dstx, int dsty) override {
void drawSurface(const Surface* src, int dstx, int dsty) override {
gfx::Clip clip(dstx, dsty, 0, 0,
((SkiaSurface*)src)->width(),
((SkiaSurface*)src)->height());
@ -393,7 +389,7 @@ public:
SkCanvas::kStrict_SrcRectConstraint);
}
void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) override {
void drawRgbaSurface(const Surface* src, int dstx, int dsty) override {
gfx::Clip clip(dstx, dsty, 0, 0,
((SkiaSurface*)src)->width(),
((SkiaSurface*)src)->height());
@ -412,9 +408,9 @@ public:
SkCanvas::kStrict_SrcRectConstraint);
}
void drawColoredRgbaSurface(const LockedSurface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
void drawColoredRgbaSurface(const Surface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
gfx::Clip clip(clipbase);
if (!clip.clip(lockedWidth(), lockedHeight(), src->lockedWidth(), src->lockedHeight()))
if (!clip.clip(width(), height(), src->width(), src->height()))
return;
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h));
@ -440,25 +436,6 @@ public:
SkCanvas::kStrict_SrcRectConstraint);
}
void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) override {
CommonFont* commonFont = static_cast<CommonFont*>(font);
gfx::Rect charBounds = commonFont->getCharBounds(chr);
if (!charBounds.isEmpty()) {
ScopedSurfaceLock lock(commonFont->getSurfaceSheet());
drawColoredRgbaSurface(lock, fg, bg, gfx::Clip(x, y, charBounds));
}
}
void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) override {
base::utf8_const_iterator it(str.begin()), end(str.end());
while (it != end) {
drawChar(font, fg, bg, x, y, *it);
x += font->charWidth(*it);
++it;
}
}
SkBitmap& bitmap() {
return m_bitmap;
}
@ -484,6 +461,7 @@ private:
SkCanvas* m_canvas;
SkPaint m_paint;
gfx::Rect m_clip;
int m_lock;
};
} // namespace she

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2013, 2015 David Capello
// Copyright (C) 2012-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -8,11 +8,20 @@
#define SHE_SURFACE_H_INCLUDED
#pragma once
#include "gfx/color.h"
#include "gfx/fwd.h"
#include "she/surface_format.h"
#include <string>
namespace gfx {
class Clip;
}
namespace she {
class LockedSurface;
class Font;
class SurfaceLock;
enum class DrawMode {
Solid,
@ -34,16 +43,43 @@ namespace she {
virtual void setDrawMode(DrawMode mode, int param = 0) = 0;
virtual LockedSurface* lock() = 0;
virtual void lock() = 0;
virtual void unlock() = 0;
virtual void clear() = 0;
virtual uint8_t* getData(int x, int y) const = 0;
virtual void getFormat(SurfaceFormatData* formatData) const = 0;
virtual gfx::Color getPixel(int x, int y) const = 0;
virtual void putPixel(gfx::Color color, int x, int y) = 0;
virtual void drawHLine(gfx::Color color, int x, int y, int w) = 0;
virtual void drawVLine(gfx::Color color, int x, int y, int h) = 0;
virtual void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b) = 0;
virtual void drawRect(gfx::Color color, const gfx::Rect& rc) = 0;
virtual void fillRect(gfx::Color color, const gfx::Rect& rc) = 0;
virtual void blitTo(Surface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const = 0;
virtual void scrollTo(const gfx::Rect& rc, int dx, int dy) = 0;
virtual void drawSurface(const Surface* src, int dstx, int dsty) = 0;
virtual void drawRgbaSurface(const Surface* src, int dstx, int dsty) = 0;
virtual void drawColoredRgbaSurface(const Surface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clip) = 0;
virtual void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) = 0;
virtual void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) = 0;
virtual void applyScale(int scaleFactor) = 0;
virtual void* nativeHandle() = 0;
};
class NonDisposableSurface : public Surface {
class SurfaceLock {
public:
virtual ~NonDisposableSurface() { }
SurfaceLock(Surface* surface) : m_surface(surface) { m_surface->lock(); }
~SurfaceLock() { m_surface->unlock(); }
private:
virtual void dispose() = 0;
Surface* m_surface;
};
} // namespace she

View File

@ -46,7 +46,8 @@ namespace she {
virtual Surface* createRgbaSurface(int width, int height) = 0;
virtual Surface* loadSurface(const char* filename) = 0;
virtual Surface* loadRgbaSurface(const char* filename) = 0;
virtual Font* loadBitmapFont(const char* filename, int scale = 1) = 0;
virtual Font* loadSpriteSheetFont(const char* filename, int scale = 1) = 0;
virtual Font* loadTrueTypeFont(const char* filename, int height) = 0;
virtual Clipboard* createClipboard() = 0;
};

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -102,29 +102,33 @@ void Entry::hideCaret()
void Entry::setCaretPos(int pos)
{
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(text().begin());
auto utf8_begin = base::utf8_const_iterator(text().begin());
auto utf8_end = base::utf8_const_iterator(text().end());
int textlen = base::utf8_length(text());
int x, c;
m_caret = pos;
m_caret = MID(0, pos, textlen);
// Backward scroll
if (m_caret < m_scroll)
if (m_scroll > m_caret)
m_scroll = m_caret;
// Forward scroll
m_scroll--;
do {
x = bounds().x + border().left();
for (c=++m_scroll; ; c++) {
int ch = (c < textlen ? *(utf8_begin+c) : ' ');
--m_scroll;
int c;
while (true) {
c = ++m_scroll;
auto utf8_it = utf8_begin + MID(0, c, textlen);
int x = bounds().x + border().left()
- font()->charWidth(' '); // Space for the carret
for (; utf8_it != utf8_end; ++c, ++utf8_it) {
int ch = *utf8_it;
x += font()->charWidth(ch);
if (x >= bounds().x2()-border().right())
break;
}
} while (m_caret >= c);
if (m_caret < c || utf8_it == utf8_end)
break;
}
m_timer.start();
m_state = true;
@ -322,8 +326,8 @@ bool Entry::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(text().begin());
base::utf8_const_iterator utf8_end = base::utf8_const_iterator(text().end());
auto utf8_begin = base::utf8_const_iterator(text().begin());
auto utf8_end = base::utf8_const_iterator(text().end());
int textlen = base::utf8_length(text());
int c, x;
@ -342,10 +346,12 @@ bool Entry::onProcessMessage(Message* msg)
// Forward scroll
else if (mousePos.x >= bounds().x2()) {
if (m_scroll < textlen - getAvailableTextLength()) {
m_scroll++;
++m_scroll;
x = bounds().x + border().left();
for (c=m_scroll; utf8_begin != utf8_end; ++c) {
int ch = (c < textlen ? *(utf8_begin+c) : ' ');
auto utf8_it = utf8_begin + MID(0, m_scroll, textlen);
for (c=m_scroll; utf8_it != utf8_end; ++c, ++utf8_it) {
int ch = (c < textlen ? *utf8_it: ' ');
x += font()->charWidth(ch);
if (x > bounds().x2()-border().right()) {
@ -353,7 +359,7 @@ bool Entry::onProcessMessage(Message* msg)
break;
}
}
m_caret = c;
m_caret = MID(0, c, textlen);
move = false;
is_dirty = true;
invalidate();
@ -450,8 +456,9 @@ void Entry::onSetText()
{
Widget::onSetText();
if (m_caret >= 0 && (std::size_t)m_caret > textLength())
m_caret = (int)textLength();
int textlen = textLength();
if (m_caret >= 0 && m_caret > textlen)
m_caret = textlen;
}
void Entry::onChange()
@ -482,11 +489,7 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
int x = bounds.x;
base::utf8_const_iterator utf8_it =
(m_scroll < textlen ?
utf8_begin + m_scroll:
utf8_end);
auto utf8_it = utf8_begin + MID(0, m_scroll, textlen);
int c = m_scroll;
for (; utf8_it != utf8_end; ++c, ++utf8_it) {
int w = font()->charWidth(*utf8_it);
@ -505,7 +508,7 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
}
}
return caret;
return MID(0, caret, textlen);
}
void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)

View File

@ -18,7 +18,6 @@
#include "gfx/size.h"
#include "she/display.h"
#include "she/font.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/manager.h"
@ -83,32 +82,32 @@ void Graphics::setDrawMode(DrawMode mode, int param)
gfx::Color Graphics::getPixel(int x, int y)
{
she::ScopedSurfaceLock dst(m_surface);
return dst->getPixel(m_dx+x, m_dy+y);
she::SurfaceLock lock(m_surface);
return m_surface->getPixel(m_dx+x, m_dy+y);
}
void Graphics::putPixel(gfx::Color color, int x, int y)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, 1, 1));
she::ScopedSurfaceLock dst(m_surface);
dst->putPixel(color, m_dx+x, m_dy+y);
she::SurfaceLock lock(m_surface);
m_surface->putPixel(color, m_dx+x, m_dy+y);
}
void Graphics::drawHLine(gfx::Color color, int x, int y, int w)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, w, 1));
she::ScopedSurfaceLock dst(m_surface);
dst->drawHLine(color, m_dx+x, m_dy+y, w);
she::SurfaceLock lock(m_surface);
m_surface->drawHLine(color, m_dx+x, m_dy+y, w);
}
void Graphics::drawVLine(gfx::Color color, int x, int y, int h)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, 1, h));
she::ScopedSurfaceLock dst(m_surface);
dst->drawVLine(color, m_dx+x, m_dy+y, h);
she::SurfaceLock lock(m_surface);
m_surface->drawVLine(color, m_dx+x, m_dy+y, h);
}
void Graphics::drawLine(gfx::Color color, const gfx::Point& _a, const gfx::Point& _b)
@ -117,8 +116,8 @@ void Graphics::drawLine(gfx::Color color, const gfx::Point& _a, const gfx::Point
gfx::Point b(m_dx+_b.x, m_dy+_b.y);
dirty(gfx::Rect(a, b));
she::ScopedSurfaceLock dst(m_surface);
dst->drawLine(color, a, b);
she::SurfaceLock lock(m_surface);
m_surface->drawLine(color, a, b);
}
void Graphics::drawRect(gfx::Color color, const gfx::Rect& rcOrig)
@ -127,8 +126,8 @@ void Graphics::drawRect(gfx::Color color, const gfx::Rect& rcOrig)
rc.offset(m_dx, m_dy);
dirty(rc);
she::ScopedSurfaceLock dst(m_surface);
dst->drawRect(color, rc);
she::SurfaceLock lock(m_surface);
m_surface->drawRect(color, rc);
}
void Graphics::fillRect(gfx::Color color, const gfx::Rect& rcOrig)
@ -137,8 +136,8 @@ void Graphics::fillRect(gfx::Color color, const gfx::Rect& rcOrig)
rc.offset(m_dx, m_dy);
dirty(rc);
she::ScopedSurfaceLock dst(m_surface);
dst->fillRect(color, rc);
she::SurfaceLock lock(m_surface);
m_surface->fillRect(color, rc);
}
void Graphics::fillRegion(gfx::Color color, const gfx::Region& rgn)
@ -163,27 +162,27 @@ void Graphics::drawSurface(she::Surface* surface, int x, int y)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, surface->width(), surface->height()));
she::ScopedSurfaceLock src(surface);
she::ScopedSurfaceLock dst(m_surface);
dst->drawSurface(src, m_dx+x, m_dy+y);
she::SurfaceLock lockSrc(surface);
she::SurfaceLock lockDst(m_surface);
m_surface->drawSurface(surface, m_dx+x, m_dy+y);
}
void Graphics::drawRgbaSurface(she::Surface* surface, int x, int y)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, surface->width(), surface->height()));
she::ScopedSurfaceLock src(surface);
she::ScopedSurfaceLock dst(m_surface);
dst->drawRgbaSurface(src, m_dx+x, m_dy+y);
she::SurfaceLock lockSrc(surface);
she::SurfaceLock lockDst(m_surface);
m_surface->drawRgbaSurface(surface, m_dx+x, m_dy+y);
}
void Graphics::drawColoredRgbaSurface(she::Surface* surface, gfx::Color color, int x, int y)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, surface->width(), surface->height()));
she::ScopedSurfaceLock src(surface);
she::ScopedSurfaceLock dst(m_surface);
dst->drawColoredRgbaSurface(src, color, gfx::ColorNone,
she::SurfaceLock lockSrc(surface);
she::SurfaceLock lockDst(m_surface);
m_surface->drawColoredRgbaSurface(surface, color, gfx::ColorNone,
gfx::Clip(m_dx+x, m_dy+y, 0, 0, surface->width(), surface->height()));
}
@ -191,9 +190,9 @@ void Graphics::blit(she::Surface* srcSurface, int srcx, int srcy, int dstx, int
{
dirty(gfx::Rect(m_dx+dstx, m_dy+dsty, w, h));
she::ScopedSurfaceLock src(srcSurface);
she::ScopedSurfaceLock dst(m_surface);
src->blitTo(dst, srcx, srcy, m_dx+dstx, m_dy+dsty, w, h);
she::SurfaceLock lockSrc(srcSurface);
she::SurfaceLock lockDst(m_surface);
srcSurface->blitTo(m_surface, srcx, srcy, m_dx+dstx, m_dy+dsty, w, h);
}
void Graphics::setFont(she::Font* font)
@ -205,8 +204,8 @@ void Graphics::drawChar(int chr, gfx::Color fg, gfx::Color bg, int x, int y)
{
dirty(gfx::Rect(gfx::Point(m_dx+x, m_dy+y), measureChar(chr)));
she::ScopedSurfaceLock dst(m_surface);
dst->drawChar(m_font, fg, bg, m_dx+x, m_dy+y, chr);
she::SurfaceLock lock(m_surface);
m_surface->drawChar(m_font, fg, bg, m_dx+x, m_dy+y, chr);
}
void Graphics::drawString(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& ptOrig)
@ -214,14 +213,14 @@ void Graphics::drawString(const std::string& str, gfx::Color fg, gfx::Color bg,
gfx::Point pt(m_dx+ptOrig.x, m_dy+ptOrig.y);
dirty(gfx::Rect(pt.x, pt.y, m_font->textLength(str), m_font->height()));
she::ScopedSurfaceLock dst(m_surface);
dst->drawString(m_font, fg, bg, pt.x, pt.y, str);
she::SurfaceLock lock(m_surface);
m_surface->drawString(m_font, fg, bg, pt.x, pt.y, str);
}
void Graphics::drawUIString(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt,
bool drawUnderscore)
{
she::ScopedSurfaceLock dst(m_surface);
she::SurfaceLock lock(m_surface);
base::utf8_const_iterator it(str.begin()), end(str.end());
int x = m_dx+pt.x;
int y = m_dy+pt.y;
@ -236,14 +235,14 @@ void Graphics::drawUIString(const std::string& str, gfx::Color fg, gfx::Color bg
underscored_w = m_font->charWidth(*it);
}
}
dst->drawChar(m_font, fg, bg, x, y, *it);
m_surface->drawChar(m_font, fg, bg, x, y, *it);
x += m_font->charWidth(*it);
++it;
}
y += m_font->height();
if (drawUnderscore && underscored_w > 0) {
dst->fillRect(fg,
m_surface->fillRect(fg,
gfx::Rect(underscored_x, y, underscored_w, guiscale()));
y += guiscale();
}

View File

@ -19,7 +19,6 @@
#include "she/display.h"
#include "she/event.h"
#include "she/event_queue.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/intern.h"
@ -574,7 +573,7 @@ void Manager::enqueueMessage(Message* msg)
#ifdef REPORT_EVENTS
if (msg->type() == kKeyDownMessage ||
msg->type() == kKeyUpMessage) {
int mods = (int)static_cast<KeyMessage*>(msg)->keyModifiers();
int mods = (int)static_cast<KeyMessage*>(msg)->modifiers();
TRACE("Key%s scancode=%d unicode=%d mods=%s%s%s\n",
(msg->type() == kKeyDownMessage ? "Down": "Up"),
static_cast<KeyMessage*>(msg)->scancode(),
@ -716,8 +715,8 @@ void Manager::setMouse(Widget* widget)
std::cout << "Manager::setMouse ";
if (widget) {
std::cout << typeid(*widget).name();
if (!widget->getId().empty())
std::cout << " (" << widget->getId() << ")";
if (!widget->id().empty())
std::cout << " (" << widget->id() << ")";
}
else {
std::cout << "null";
@ -1258,8 +1257,8 @@ void Manager::pumpQueue()
std::cout << "Event " << msg->type() << " (" << string << ") "
<< "for " << typeid(*widget).name();
if (!widget->getId().empty())
std::cout << " (" << widget->getId() << ")";
if (!widget->id().empty())
std::cout << " (" << widget->id() << ")";
std::cout << std::endl;
}
#endif
@ -1271,7 +1270,7 @@ void Manager::pumpQueue()
continue;
PaintMessage* paintMsg = static_cast<PaintMessage*>(msg);
she::NonDisposableSurface* surface = m_display->getSurface();
she::Surface* surface = m_display->getSurface();
gfx::Rect oldClip = surface->getClipBounds();
if (surface->intersectClipRect(paintMsg->rect())) {
@ -1286,8 +1285,8 @@ void Manager::pumpQueue()
#ifdef DEBUG_PAINT_EVENTS
{
she::ScopedSurfaceLock lock(surface);
lock->fillRect(gfx::rgba(0, 0, 255), paintMsg->rect());
she::SurfaceLock lock(surface);
surface->fillRect(gfx::rgba(0, 0, 255), paintMsg->rect());
}
if (m_display)

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -11,8 +11,6 @@
#include "ui/manager.h"
#include "she/display.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
@ -30,13 +28,14 @@ void move_region(Manager* manager, const Region& region, int dx, int dy)
if (!display)
return;
she::ScopedSurfaceLock lock(display->getSurface());
she::Surface* surface = display->getSurface();
she::SurfaceLock lock(surface);
std::size_t nrects = region.size();
// Blit directly screen to screen.
if (nrects == 1) {
gfx::Rect rc = region[0];
lock->scrollTo(rc, dx, dy);
surface->scrollTo(rc, dx, dy);
rc.offset(dx, dy);
Manager::getDefault()->dirtyRect(rc);
@ -45,28 +44,27 @@ void move_region(Manager* manager, const Region& region, int dx, int dy)
else if (nrects > 1) {
std::vector<she::Surface*> images(nrects);
Region::const_iterator it, begin=region.begin(), end=region.end();
she::Surface* sur;
int c;
for (c=0, it=begin; it != end; ++it, ++c) {
const Rect& rc = *it;
sur = system->createSurface(rc.w, rc.h);
she::Surface* tmpSur = system->createSurface(rc.w, rc.h);
{
she::ScopedSurfaceLock surlock(sur);
lock->blitTo(surlock, rc.x, rc.y, 0, 0, rc.w, rc.h);
she::SurfaceLock tmpSurLock(tmpSur);
surface->blitTo(tmpSur, rc.x, rc.y, 0, 0, rc.w, rc.h);
}
images[c] = sur;
images[c] = tmpSur;
}
for (c=0, it=begin; it != end; ++it, ++c) {
gfx::Rect rc((*it).x+dx, (*it).y+dy, (*it).w, (*it).h);
sur = images[c];
she::Surface* tmpSur = images[c];
{
she::ScopedSurfaceLock surlock(sur);
surlock->blitTo(lock, 0, 0, rc.x, rc.y, rc.w, rc.h);
she::SurfaceLock tmpSurLock(tmpSur);
tmpSur->blitTo(surface, 0, 0, rc.x, rc.y, rc.w, rc.h);
manager->dirtyRect(rc);
}
sur->dispose();
tmpSur->dispose();
}
}
}

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -10,8 +10,7 @@
#include "ui/overlay.h"
#include "she/locked_surface.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/manager.h"
@ -55,13 +54,13 @@ gfx::Rect Overlay::bounds() const
return gfx::Rect(0, 0, 0, 0);
}
void Overlay::drawOverlay(she::LockedSurface* screen)
void Overlay::drawOverlay(she::Surface* screen)
{
if (!m_surface)
return;
she::ScopedSurfaceLock lockedSurface(m_surface);
screen->drawRgbaSurface(lockedSurface, m_pos.x, m_pos.y);
she::SurfaceLock lock(m_surface);
screen->drawRgbaSurface(m_surface, m_pos.x, m_pos.y);
Manager::getDefault()->dirtyRect(
gfx::Rect(m_pos.x, m_pos.y,
@ -74,7 +73,7 @@ void Overlay::moveOverlay(const gfx::Point& newPos)
m_pos = newPos;
}
void Overlay::captureOverlappedArea(she::LockedSurface* screen)
void Overlay::captureOverlappedArea(she::Surface* screen)
{
if (!m_surface)
return;
@ -82,12 +81,12 @@ void Overlay::captureOverlappedArea(she::LockedSurface* screen)
if (!m_overlap)
m_overlap = she::instance()->createSurface(m_surface->width(), m_surface->height());
she::ScopedSurfaceLock lock(m_overlap);
screen->blitTo(lock, m_pos.x, m_pos.y, 0, 0,
she::SurfaceLock lock(m_overlap);
screen->blitTo(m_overlap, m_pos.x, m_pos.y, 0, 0,
m_overlap->width(), m_overlap->height());
}
void Overlay::restoreOverlappedArea(she::LockedSurface* screen)
void Overlay::restoreOverlappedArea(she::Surface* screen)
{
if (!m_surface)
return;
@ -95,9 +94,9 @@ void Overlay::restoreOverlappedArea(she::LockedSurface* screen)
if (!m_overlap)
return;
she::ScopedSurfaceLock lock(m_overlap);
lock->blitTo(screen, 0, 0, m_pos.x, m_pos.y,
m_overlap->width(), m_overlap->height());
she::SurfaceLock lock(m_overlap);
m_overlap->blitTo(screen, 0, 0, m_pos.x, m_pos.y,
m_overlap->width(), m_overlap->height());
Manager::getDefault()->dirtyRect(
gfx::Rect(m_pos.x, m_pos.y,

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -14,7 +14,6 @@
namespace she {
class Surface;
class LockedSurface;
}
namespace ui {
@ -34,10 +33,10 @@ namespace ui {
const gfx::Point& position() const { return m_pos; }
gfx::Rect bounds() const;
void captureOverlappedArea(she::LockedSurface* screen);
void restoreOverlappedArea(she::LockedSurface* screen);
void captureOverlappedArea(she::Surface* screen);
void restoreOverlappedArea(she::Surface* screen);
void drawOverlay(she::LockedSurface* screen);
void drawOverlay(she::Surface* screen);
void moveOverlay(const gfx::Point& newPos);
bool operator<(const Overlay& other) const {

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2001-2013, 2015 David Capello
// Copyright (C) 2001-2013, 2015, 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -11,7 +11,7 @@
#include "ui/overlay_manager.h"
#include "she/display.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "ui/manager.h"
#include "ui/overlay.h"
@ -66,9 +66,9 @@ void OverlayManager::captureOverlappedAreas()
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
she::SurfaceLock lock(displaySurface);
for (Overlay* overlay : *this)
overlay->captureOverlappedArea(lockedDisplaySurface);
overlay->captureOverlappedArea(displaySurface);
}
void OverlayManager::restoreOverlappedAreas()
@ -78,9 +78,9 @@ void OverlayManager::restoreOverlappedAreas()
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
she::SurfaceLock lock(displaySurface);
for (Overlay* overlay : *this)
overlay->restoreOverlappedArea(lockedDisplaySurface);
overlay->restoreOverlappedArea(displaySurface);
}
void OverlayManager::drawOverlays()
@ -90,9 +90,9 @@ void OverlayManager::drawOverlays()
return;
she::Surface* displaySurface = manager->getDisplay()->getSurface();
she::ScopedSurfaceLock lockedDisplaySurface(displaySurface);
she::SurfaceLock lock(displaySurface);
for (Overlay* overlay : *this)
overlay->drawOverlay(lockedDisplaySurface);
overlay->drawOverlay(displaySurface);
}
} // namespace ui

View File

@ -27,7 +27,7 @@
#ifdef DEBUG_SCROLL_EVENTS
#include "base/thread.h"
#include "she/display.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#endif
#include <queue>
@ -326,9 +326,10 @@ void View::onSetViewScroll(const gfx::Point& pt)
display->flip(gfx::Rect(0, 0, display_w(), display_h()));
base::this_thread::sleep_for(0.002);
{
she::ScopedSurfaceLock lock(display->getSurface());
she::Surface* surface = display->getSurface();
she::SurfaceLock lock(surface);
for (const auto& rc : invalidRegion)
lock->fillRect(gfx::rgba(255, 0, 0), rc);
surface->fillRect(gfx::rgba(255, 0, 0), rc);
}
if (display)
display->flip(gfx::Rect(0, 0, display_w(), display_h()));

View File

@ -4,7 +4,7 @@
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
/* #define REPORT_SIGNALS */
// #define REPORT_SIGNALS
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -13,9 +13,9 @@
#include "ui/widget.h"
#include "base/memory.h"
#include "base/string.h"
#include "she/display.h"
#include "she/font.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/init_theme_event.h"
@ -125,6 +125,11 @@ double Widget::textDouble() const
return strtod(m_text.c_str(), NULL);
}
int Widget::textLength() const
{
return base::utf8_length(text());
}
void Widget::setText(const std::string& text)
{
setTextQuiet(text);
@ -1055,9 +1060,11 @@ public:
void operator()(Graphics* graphics) {
{
she::ScopedSurfaceLock src(m_surface);
she::ScopedSurfaceLock dst(she::instance()->defaultDisplay()->getSurface());
src->blitTo(dst, 0, 0, m_pt.x, m_pt.y,
she::Surface* dst = she::instance()->defaultDisplay()->getSurface();
she::SurfaceLock lockSrc(m_surface);
she::SurfaceLock lockDst(dst);
m_surface->blitTo(
dst, 0, 0, m_pt.x, m_pt.y,
m_surface->width(), m_surface->height());
}
m_surface->dispose();

View File

@ -82,7 +82,7 @@ namespace ui {
const std::string& text() const { return m_text; }
int textInt() const;
double textDouble() const;
std::size_t textLength() const { return m_text.size(); }
int textLength() const;
void setText(const std::string& text);
void setTextf(const char* text, ...);
void setTextQuiet(const std::string& text);

View File

@ -1,50 +0,0 @@
/*
* Copyright © 2008 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Author: Carl D. Worth <cworth@cworth.org>
*/
#ifndef PIXMAN_VERSION_H__
#define PIXMAN_VERSION_H__
#ifndef PIXMAN_H__
# error pixman-version.h should only be included by pixman.h
#endif
#define PIXMAN_VERSION_MAJOR @PIXMAN_VERSION_MAJOR@
#define PIXMAN_VERSION_MINOR @PIXMAN_VERSION_MINOR@
#define PIXMAN_VERSION_MICRO @PIXMAN_VERSION_MICRO@
#define PIXMAN_VERSION_STRING "@PIXMAN_VERSION_MAJOR@.@PIXMAN_VERSION_MINOR@.@PIXMAN_VERSION_MICRO@"
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
((major) * 10000) \
+ ((minor) * 100) \
+ ((micro) * 1))
#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \
PIXMAN_VERSION_MAJOR, \
PIXMAN_VERSION_MINOR, \
PIXMAN_VERSION_MICRO)
#endif /* PIXMAN_VERSION_H__ */