diff --git a/src/app/file_system.cpp b/src/app/file_system.cpp index 58f90ba67..4c9d44edc 100644 --- a/src/app/file_system.cpp +++ b/src/app/file_system.cpp @@ -29,6 +29,7 @@ #include "base/path.h" #include "base/string.h" +#include "she/surface.h" #include #include @@ -147,13 +148,13 @@ public: bool hasExtension(const std::string& csv_extensions); - BITMAP* getThumbnail(); - void setThumbnail(BITMAP* thumbnail); + she::Surface* getThumbnail(); + void setThumbnail(she::Surface* thumbnail); }; typedef std::map FileItemMap; -typedef std::map ThumbnailMap; +typedef std::map ThumbnailMap; // the root of the file-system static FileItem* rootitem = NULL; @@ -237,7 +238,7 @@ FileSystemModule::~FileSystemModule() for (ThumbnailMap::iterator it=thumbnail_map->begin(); it!=thumbnail_map->end(); ++it) { - destroy_bitmap(it->second); + it->second->dispose(); } thumbnail_map->clear(); @@ -567,7 +568,7 @@ bool FileItem::hasExtension(const std::string& csv_extensions) return base::has_file_extension(this->filename, csv_extensions); } -BITMAP* FileItem::getThumbnail() +she::Surface* FileItem::getThumbnail() { ThumbnailMap::iterator it = thumbnail_map->find(this->filename); if (it != thumbnail_map->end()) @@ -576,12 +577,12 @@ BITMAP* FileItem::getThumbnail() return NULL; } -void FileItem::setThumbnail(BITMAP* thumbnail) +void FileItem::setThumbnail(she::Surface* thumbnail) { // destroy the current thumbnail of the file (if exists) ThumbnailMap::iterator it = thumbnail_map->find(this->filename); if (it != thumbnail_map->end()) { - destroy_bitmap(it->second); + it->second->dispose(); thumbnail_map->erase(it); } diff --git a/src/app/file_system.h b/src/app/file_system.h index 9798d5347..912314fe2 100644 --- a/src/app/file_system.h +++ b/src/app/file_system.h @@ -25,7 +25,9 @@ #include #include -struct BITMAP; +namespace she { + class Surface; +} namespace app { @@ -89,8 +91,8 @@ namespace app { virtual bool hasExtension(const std::string& csv_extensions) = 0; - virtual BITMAP* getThumbnail() = 0; - virtual void setThumbnail(BITMAP* thumbnail) = 0; + virtual she::Surface* getThumbnail() = 0; + virtual void setThumbnail(she::Surface* thumbnail) = 0; }; } // namespace app diff --git a/src/app/modules/gfx.h b/src/app/modules/gfx.h index 214501772..299c06bd6 100644 --- a/src/app/modules/gfx.h +++ b/src/app/modules/gfx.h @@ -26,9 +26,6 @@ #include "ui/color.h" #include "ui/graphics.h" -struct FONT; -struct BITMAP; - namespace app { using namespace raster; diff --git a/src/app/thumbnail_generator.cpp b/src/app/thumbnail_generator.cpp index bd857b143..1f156a185 100644 --- a/src/app/thumbnail_generator.cpp +++ b/src/app/thumbnail_generator.cpp @@ -30,14 +30,13 @@ #include "base/bind.h" #include "base/scoped_lock.h" #include "base/thread.h" -#include "raster/conversion_alleg.h" +#include "raster/conversion_she.h" #include "raster/image.h" #include "raster/palette.h" #include "raster/primitives.h" #include "raster/rotate.h" #include "raster/sprite.h" - -#include +#include "she/system.h" #define MAX_THUMBNAIL_SIZE 128 @@ -72,11 +71,11 @@ private: // Post load fop_post_load(m_fop); - // Convert the loaded document into the Allegro bitmap "m_thumbnail". + // Convert the loaded document into the she::Surface. const Sprite* sprite = (m_fop->document && m_fop->document->getSprite()) ? m_fop->document->getSprite(): NULL; if (!fop_is_stop(m_fop) && sprite) { - // The palette to convert the Image to a BITMAP + // The palette to convert the Image m_palette.reset(new Palette(*sprite->getPalette(FrameNumber(0)))); // Render the 'sprite' in one plain 'image' @@ -107,9 +106,13 @@ private: // Set the thumbnail of the file-item. if (m_thumbnail) { - BITMAP* bmp = create_bitmap_ex(16, m_thumbnail->getWidth(), m_thumbnail->getHeight()); - convert_image_to_allegro(m_thumbnail, bmp, 0, 0, m_palette); - m_fileitem->setThumbnail(bmp); + she::Surface* thumbnail = she::instance()->createRgbaSurface( + m_thumbnail->getWidth(), + m_thumbnail->getHeight()); + + convert_image_to_surface(m_thumbnail, thumbnail, 0, 0, m_palette); + + m_fileitem->setThumbnail(thumbnail); } } catch (const std::exception& e) { diff --git a/src/app/ui/color_button.cpp b/src/app/ui/color_button.cpp index 5e5e35797..9e275755c 100644 --- a/src/app/ui/color_button.cpp +++ b/src/app/ui/color_button.cpp @@ -211,7 +211,7 @@ void ColorButton::onPaint(PaintEvent& ev) gfx::Rect text; getTextIconInfo(NULL, &text); - g->drawUIString(getText(), textcolor, ColorNone, false, text.getOrigin()); + g->drawUIString(getText(), textcolor, ColorNone, text.getOrigin()); } void ColorButton::onClick(Event& ev) diff --git a/src/app/ui/color_sliders.cpp b/src/app/ui/color_sliders.cpp index 4b320d4f4..99e995c4d 100644 --- a/src/app/ui/color_sliders.cpp +++ b/src/app/ui/color_sliders.cpp @@ -83,7 +83,6 @@ namespace { private: ColorSliders::Channel m_channel; - BITMAP* m_cachedBg; app::Color m_color; }; diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index c57858331..a00f552db 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -40,7 +40,7 @@ #include "base/bind.h" #include "base/unique_ptr.h" #include "raster/brush.h" -#include "raster/conversion_alleg.h" +#include "raster/conversion_she.h" #include "raster/image.h" #include "raster/palette.h" #include "she/scoped_surface_lock.h" @@ -102,13 +102,7 @@ public: m_bitmap->dispose(); m_bitmap = she::instance()->createRgbaSurface(image->getWidth(), image->getHeight()); - { - she::ScopedSurfaceLock lock(m_bitmap); - lock->clear(); - convert_image_to_allegro(image, - reinterpret_cast(m_bitmap->nativeHandle()), - 0, 0, palette); - } + convert_image_to_surface(image, m_bitmap, 0, 0, palette); invalidate(); } diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index f130bed2f..466b8ef1f 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -27,8 +27,8 @@ #include "app/color_utils.h" #include "app/commands/commands.h" #include "app/commands/params.h" -#include "app/document_location.h" #include "app/console.h" +#include "app/document_location.h" #include "app/ini_file.h" #include "app/modules/gfx.h" #include "app/modules/gui.h" @@ -55,12 +55,14 @@ #include "app/util/render.h" #include "base/bind.h" #include "base/unique_ptr.h" -#include "raster/conversion_alleg.h" +#include "raster/conversion_she.h" #include "raster/raster.h" +#include "she/surface.h" +#include "she/system.h" #include "ui/ui.h" #include -#include +#include namespace app { @@ -394,10 +396,10 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& rc, in m_decorator->preRenderDecorator(&preRender); } - SharedPtr tmp(create_bitmap(width, height), destroy_bitmap); - convert_image_to_allegro(rendered, tmp, 0, 0, m_sprite->getPalette(m_frame)); - + she::Surface* tmp(she::instance()->createRgbaSurface(width, height)); + convert_image_to_surface(rendered, tmp, 0, 0, m_sprite->getPalette(m_frame)); g->blit(tmp, 0, 0, dest_x, dest_y, width, height); + tmp->dispose(); } } } @@ -493,7 +495,7 @@ void Editor::drawSpriteClipped(const gfx::Region& updateRegion) Region region; getDrawableRegion(region, kCutTopWindows); - Graphics g(ji_screen, 0, 0); + ScreenGraphics g; for (Region::const_iterator it=region.begin(), end=region.end(); it != end; ++it) { diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h index e8d444f0d..e1ed2253f 100644 --- a/src/app/ui/editor/editor.h +++ b/src/app/ui/editor/editor.h @@ -37,6 +37,8 @@ #define MIN_ZOOM 0 #define MAX_ZOOM 5 +struct BITMAP; + namespace raster { class Sprite; class Layer; @@ -213,7 +215,7 @@ namespace app { void forEachBrushPixel( int screen_x, int screen_y, int sprite_x, int sprite_y, int color, - void (*pixel)(BITMAP *bmp, int x, int y, int color)); + void (*pixel)(BITMAP* bmp, int x, int y, int color)); // Draws the specified portion of sprite in the editor. Warning: // You should setup the clip of the screen before calling this diff --git a/src/app/ui/file_list.cpp b/src/app/ui/file_list.cpp index 89f699ba4..5b900c465 100644 --- a/src/app/ui/file_list.cpp +++ b/src/app/ui/file_list.cpp @@ -26,6 +26,7 @@ #include "app/thumbnail_generator.h" #include "app/ui/skin/skin_theme.h" #include "she/font.h" +#include "she/surface.h" #include "ui/ui.h" #include @@ -310,7 +311,7 @@ void FileList::onPaint(ui::PaintEvent& ev) int evenRow = 0; ui::Color bgcolor; ui::Color fgcolor; - BITMAP* thumbnail = NULL; + she::Surface* thumbnail = NULL; int thumbnail_y = 0; g->fillRect(theme->getColor(ThemeColor::Background), bounds); @@ -344,19 +345,20 @@ void FileList::onPaint(ui::PaintEvent& ev) if (fi->isFolder()) { int icon_w = getFont()->textLength("[+]"); - g->drawUIString("[+]", fgcolor, bgcolor, true, gfx::Point(x, y+2*jguiscale())); + g->drawUIString("[+]", fgcolor, bgcolor, gfx::Point(x, y+2*jguiscale())); x += icon_w+2*jguiscale(); } // item name g->drawString( fi->getDisplayName().c_str(), - fgcolor, bgcolor, true, gfx::Point(x, y+2*jguiscale())); + fgcolor, bgcolor, gfx::Point(x, y+2*jguiscale())); // draw progress bars double progress; ThumbnailGenerator::WorkerStatus workerStatus = ThumbnailGenerator::instance()->getWorkerStatus(fi, progress); + if (workerStatus == ThumbnailGenerator::WorkingOnThumbnail) { int barw = 64*jguiscale(); @@ -381,15 +383,15 @@ void FileList::onPaint(ui::PaintEvent& ev) // Draw the thumbnail if (thumbnail) { - x = vp.x+vp.w-2*jguiscale()-thumbnail->w; - y = thumbnail_y-thumbnail->h/2+getBounds().y; - y = MID(vp.y+2*jguiscale(), y, vp.y+vp.h-3*jguiscale()-thumbnail->h); + x = vp.x+vp.w - 2*jguiscale() - thumbnail->width(); + y = thumbnail_y - thumbnail->height()/2 + getBounds().y; + y = MID(vp.y+2*jguiscale(), y, vp.y+vp.h-3*jguiscale()-thumbnail->height()); x -= getBounds().x; y -= getBounds().y; - g->blit(thumbnail, 0, 0, x, y, thumbnail->w, thumbnail->h); + g->blit(thumbnail, 0, 0, x, y, thumbnail->width(), thumbnail->height()); g->drawRect(ui::rgba(0, 0, 0), - gfx::Rect(x-1, y-1, thumbnail->w+1, thumbnail->h+1)); + gfx::Rect(x-1, y-1, thumbnail->width()+1, thumbnail->height()+1)); } } diff --git a/src/app/ui/resources_listbox.cpp b/src/app/ui/resources_listbox.cpp index 390603355..9c63e4d76 100644 --- a/src/app/ui/resources_listbox.cpp +++ b/src/app/ui/resources_listbox.cpp @@ -90,7 +90,7 @@ protected: // box.x += box.w; // } - g->drawString(getText(), fgcolor, ui::ColorNone, false, + g->drawString(getText(), fgcolor, ui::ColorNone, gfx::Point( bounds.x + jguiscale()*2, bounds.y + bounds.h/2 - g->measureUIString(getText()).h/2)); diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp index b540f8e16..8f0c0cb18 100644 --- a/src/app/ui/skin/skin_theme.cpp +++ b/src/app/ui/skin/skin_theme.cpp @@ -1002,7 +1002,7 @@ void SkinTheme::paintButton(PaintEvent& ev) draw_bounds_nw(g, widget->getClientBounds(), part_nw, bg); // text - drawTextString(g, NULL, fg, bg, false, widget, + drawTextString(g, NULL, fg, ColorNone, widget, widget->getClientChildrenBounds(), get_button_selected_offset()); // Paint the icon @@ -1047,7 +1047,7 @@ void SkinTheme::paintCheckBox(PaintEvent& ev) } // Text - drawTextString(g, NULL, ColorNone, bg, false, widget, text, 0); + drawTextString(g, NULL, ColorNone, ColorNone, widget, text, 0); // Paint the icon if (iconInterface) @@ -1167,7 +1167,7 @@ void SkinTheme::paintLabel(PaintEvent& ev) rc.shrink(widget->getBorder()); widget->getTextIconInfo(NULL, &text); - g->drawUIString(widget->getText(), fg, bg, false, text.getOrigin()); + g->drawUIString(widget->getText(), fg, ColorNone, text.getOrigin()); } void SkinTheme::paintLinkLabel(PaintEvent& ev) @@ -1179,7 +1179,7 @@ void SkinTheme::paintLinkLabel(PaintEvent& ev) ui::Color bg = BGCOLOR; g->fillRect(bg, bounds); - drawTextString(g, NULL, fg, bg, false, widget, bounds, 0); + drawTextString(g, NULL, fg, ColorNone, widget, bounds, 0); // Underline style if (widget->hasMouseOver()) { @@ -1221,7 +1221,7 @@ void SkinTheme::paintListItem(ui::PaintEvent& ev) if (widget->hasText()) { bounds.shrink(widget->getBorder()); - drawTextString(g, NULL, fg, bg, true, widget, bounds, 0); + drawTextString(g, NULL, fg, bg, widget, bounds, 0); } } @@ -1292,7 +1292,7 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev) Rect pos = bounds; if (!bar) pos.offset(widget->child_spacing/2, 0); - drawTextString(g, NULL, fg, bg, false, widget, pos, 0); + drawTextString(g, NULL, fg, ColorNone, widget, pos, 0); // For menu-box if (!bar) { @@ -1328,7 +1328,7 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev) std::string buf = widget->getAccel()->toString(); widget->setAlign(JI_RIGHT | JI_MIDDLE); - drawTextString(g, buf.c_str(), fg, bg, false, widget, pos, 0); + drawTextString(g, buf.c_str(), fg, ColorNone, widget, pos, 0); widget->setAlign(old_align); } } @@ -1368,7 +1368,7 @@ void SkinTheme::paintRadioButton(PaintEvent& ev) } // Text - drawTextString(g, NULL, ColorNone, bg, false, widget, text, 0); + drawTextString(g, NULL, ColorNone, ColorNone, widget, text, 0); // Icon if (iconInterface) @@ -1406,7 +1406,7 @@ void SkinTheme::paintSeparator(ui::PaintEvent& ev) bounds.y2() - widget->border_width.b/2 + h)); drawTextString(g, NULL, - getColorById(kSeparatorLabelColorId), BGCOLOR, false, + getColorById(kSeparatorLabelColorId), BGCOLOR, widget, r, 0); } } @@ -1517,8 +1517,8 @@ void SkinTheme::paintSlider(PaintEvent& ev) IntersectClip clip(g, Rect(rc.x, rc.y, x-rc.x, rc.h)); if (clip) { drawTextString(g, NULL, - getColor(ThemeColor::SliderFullText), - getColor(ThemeColor::SliderFullFace), false, widget, rc, 0); + getColor(ThemeColor::SliderFullText), ColorNone, + widget, rc, 0); } } @@ -1527,7 +1527,7 @@ void SkinTheme::paintSlider(PaintEvent& ev) if (clip) { drawTextString(g, NULL, getColor(ThemeColor::SliderEmptyText), - getColor(ThemeColor::SliderEmptyFace), false, widget, rc, 0); + ColorNone, widget, rc, 0); } } @@ -1857,7 +1857,7 @@ ui::Color SkinTheme::getWidgetBgColor(Widget* widget) } void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color, - bool fill_bg, Widget* widget, const Rect& rc, + Widget* widget, const Rect& rc, int selected_offset) { if (t || widget->hasText()) { @@ -1910,16 +1910,11 @@ void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, u IntersectClip clip(g, textWrap); if (clip) { if (!widget->isEnabled()) { - // TODO avoid this - if (fill_bg) // Only to draw the background - g->drawUIString(t, ColorNone, bg_color, fill_bg, textrc.getOrigin()); - // Draw white part - g->drawUIString(t, getColor(ThemeColor::Background), bg_color, fill_bg, + g->drawUIString(t, + getColor(ThemeColor::Background), + ui::ColorNone, textrc.getOrigin() + Point(jguiscale(), jguiscale())); - - if (fill_bg) - fill_bg = false; } g->drawUIString(t, @@ -1927,7 +1922,7 @@ void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, u getColor(ThemeColor::Disabled): (ui::geta(fg_color) > 0 ? fg_color : getColor(ThemeColor::Text))), - bg_color, fill_bg, textrc.getOrigin()); + bg_color, textrc.getOrigin()); } } } diff --git a/src/app/ui/skin/skin_theme.h b/src/app/ui/skin/skin_theme.h index 3aacceef5..14631aa0e 100644 --- a/src/app/ui/skin/skin_theme.h +++ b/src/app/ui/skin/skin_theme.h @@ -201,7 +201,7 @@ namespace app { she::Surface* sliceSheet(she::Surface* sur, const gfx::Rect& bounds); ui::Color getWidgetBgColor(ui::Widget* widget); void drawTextString(ui::Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color, - bool fill_bg, ui::Widget* widget, const gfx::Rect& rc, + ui::Widget* widget, const gfx::Rect& rc, int selected_offset); void drawEntryCaret(ui::Graphics* g, ui::Entry* widget, int x, int y); diff --git a/src/app/ui/status_bar.cpp b/src/app/ui/status_bar.cpp index 5e126459b..0b46b90f9 100644 --- a/src/app/ui/status_bar.cpp +++ b/src/app/ui/status_bar.cpp @@ -513,7 +513,7 @@ void StatusBar::onPaint(ui::PaintEvent& ev) str += buf; } - g->drawString(str, textColor, ColorNone, false, + g->drawString(str, textColor, ColorNone, gfx::Point(x, rc.y + rc.h/2 - getFont()->height()/2)); x += getFont()->textLength(str.c_str()) + 4*jguiscale(); @@ -531,7 +531,7 @@ void StatusBar::onPaint(ui::PaintEvent& ev) // Status bar text if (getTextLength() > 0) { - g->drawString(getText(), textColor, ColorNone, false, + g->drawString(getText(), textColor, ColorNone, gfx::Point(x, rc.y + rc.h/2 - getFont()->height()/2)); x += getFont()->textLength(getText().c_str()) + 4*jguiscale(); diff --git a/src/app/ui/tabs.cpp b/src/app/ui/tabs.cpp index 56299adee..1a10e3cc4 100644 --- a/src/app/ui/tabs.cpp +++ b/src/app/ui/tabs.cpp @@ -497,7 +497,7 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, boo PART_TAB_NORMAL_NW, face_color); - g->drawString(tab->text, text_color, face_color, false, + g->drawString(tab->text, text_color, ColorNone, gfx::Point( box.x + 4*jguiscale(), box.y + box.h/2 - getFont()->height()/2+1 + y_delta)); diff --git a/src/raster/CMakeLists.txt b/src/raster/CMakeLists.txt index cb07fa1af..21b6c1741 100644 --- a/src/raster/CMakeLists.txt +++ b/src/raster/CMakeLists.txt @@ -14,6 +14,7 @@ add_library(raster-lib cel_io.cpp color_scales.cpp conversion_alleg.cpp + conversion_she.cpp dirty.cpp dirty_io.cpp file/col_file.cpp diff --git a/src/raster/conversion_she.cpp b/src/raster/conversion_she.cpp new file mode 100644 index 000000000..adf80cc3a --- /dev/null +++ b/src/raster/conversion_she.cpp @@ -0,0 +1,149 @@ +/* Aseprite + * Copyright (C) 2001-2014 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "raster/conversion_she.h" + +#include "raster/algo.h" +#include "raster/blend.h" +#include "raster/color_scales.h" +#include "raster/image.h" +#include "raster/image_impl.h" +#include "raster/palette.h" +#include "raster/rgbmap.h" +#include "she/surface.h" +#include "she/surface_format.h" +#include "she/scoped_surface_lock.h" + +namespace raster { + +namespace { + +template +uint32_t convert_color_to_surface(color_t color, const Palette* palette, const she::SurfaceFormatData* fd) { + // Error, it must use a specialization + + // TODO Use a static_assert(false) +} + +template<> +uint32_t convert_color_to_surface(color_t c, const Palette* palette, const she::SurfaceFormatData* fd) { + return + ((rgba_getr(c) << fd->redShift ) & fd->redMask ) | + ((rgba_getg(c) << fd->greenShift) & fd->greenMask) | + ((rgba_getb(c) << fd->blueShift ) & fd->blueMask ) | + ((rgba_geta(c) << fd->alphaShift) & fd->alphaMask); +} + +template<> +uint32_t convert_color_to_surface(color_t c, const Palette* palette, const she::SurfaceFormatData* fd) { + return + ((graya_getv(c) << fd->redShift ) & fd->redMask ) | + ((graya_getv(c) << fd->greenShift) & fd->greenMask) | + ((graya_getv(c) << fd->blueShift ) & fd->blueMask ) | + ((graya_geta(c) << fd->alphaShift) & fd->alphaMask); +} + +template<> +uint32_t convert_color_to_surface(color_t c0, const Palette* palette, const she::SurfaceFormatData* fd) { + color_t c = palette->getEntry(c0); + return + ((rgba_getr(c) << fd->redShift ) & fd->redMask ) | + ((rgba_getg(c) << fd->greenShift) & fd->greenMask) | + ((rgba_getb(c) << fd->blueShift ) & fd->blueMask ) | + ((rgba_geta(c) << fd->alphaShift) & fd->alphaMask); +} + +template<> +uint32_t convert_color_to_surface(color_t c0, const Palette* palette, const she::SurfaceFormatData* fd) { + color_t c = palette->getEntry(c0); + return + ((rgba_getr(c) << fd->redShift ) & fd->redMask ) | + ((rgba_getg(c) << fd->greenShift) & fd->greenMask) | + ((rgba_getb(c) << fd->blueShift ) & fd->blueMask ) | + ((rgba_geta(c) << fd->alphaShift) & fd->alphaMask); +} + +template +void convert_image_to_surface_templ(const Image* image, she::LockedSurface* dst, int x, int y, const Palette* palette, const she::SurfaceFormatData* fd) +{ + const LockImageBits bits(image); + typename LockImageBits::const_iterator src_it = bits.begin(), src_end = bits.end(); + int w = image->getWidth(); + int h = image->getHeight(); + + for (int v=0; vgetData(x, y)); + for (int u=0; u(*src_it, palette, fd); + ++dst_address; + ++src_it; + } + ++y; + } +} + +struct Address24bpp +{ + uint8_t* m_ptr; + Address24bpp(uint8_t* ptr) : m_ptr(ptr) { } + Address24bpp& operator++() { m_ptr += 3; return *this; } + Address24bpp& operator*() { return *this; } + Address24bpp& operator=(uint32_t c) { + WRITE3BYTES(m_ptr, c); + return *this; + } +}; + +template +void convert_image_to_surface_selector(const Image* image, she::LockedSurface* surface, int x, int y, const Palette* palette, const she::SurfaceFormatData* fd) +{ + switch (fd->bitsPerPixel) { + case 8: convert_image_to_surface_templ(image, surface, x, y, palette, fd); break; + case 15: + case 16: convert_image_to_surface_templ(image, surface, x, y, palette, fd); break; + case 24: convert_image_to_surface_templ(image, surface, x, y, palette, fd); break; + case 32: convert_image_to_surface_templ(image, surface, x, y, palette, fd); break; + } +} + +} // anonymous namespace + +void convert_image_to_surface(const Image* image, she::Surface* surface, int x, int y, const Palette* palette) +{ + she::ScopedSurfaceLock dst(surface); + she::SurfaceFormatData fd; + dst->getFormat(&fd); + + switch (image->getPixelFormat()) { + case IMAGE_RGB: convert_image_to_surface_selector(image, dst, x, y, palette, &fd); break; + case IMAGE_GRAYSCALE: convert_image_to_surface_selector(image, dst, x, y, palette, &fd); break; + case IMAGE_INDEXED: convert_image_to_surface_selector(image, dst, x, y, palette, &fd); break; + case IMAGE_BITMAP: convert_image_to_surface_selector(image, dst, x, y, palette, &fd); break; + default: + ASSERT(false); + throw std::runtime_error("conversion not supported"); + } +} + +} // namespace raster diff --git a/src/raster/conversion_she.h b/src/raster/conversion_she.h new file mode 100644 index 000000000..7f68dbe78 --- /dev/null +++ b/src/raster/conversion_she.h @@ -0,0 +1,35 @@ +/* Aseprite + * Copyright (C) 2001-2014 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef RASTER_CONVERSION_SHE_H_INCLUDED +#define RASTER_CONVERSION_SHE_H_INCLUDED +#pragma once + +namespace she { + class Surface; +} + +namespace raster { + class Image; + class Palette; + + void convert_image_to_surface(const Image* image, she::Surface* surface, int x, int y, const Palette* palette); + +} // namespace raster + +#endif diff --git a/src/she/alleg4/alleg4_surface.h b/src/she/alleg4/alleg4_surface.h index 0ecc3834d..f862ff847 100644 --- a/src/she/alleg4/alleg4_surface.h +++ b/src/she/alleg4/alleg4_surface.h @@ -12,11 +12,21 @@ #include #include "base/compiler_specific.h" +#include "base/string.h" +#include "gfx/point.h" +#include "gfx/rect.h" #include "she/locked_surface.h" #include "she/surface.h" namespace she { + inline int to_allegro(Color color) { + if (is_transparent(color)) + return -1; + else + return makecol(getr(color), getg(color), getb(color)); + } + class Alleg4Surface : public Surface , public LockedSurface { public: @@ -62,6 +72,38 @@ namespace she { return m_bmp->h; } + bool isDirectToScreen() const OVERRIDE { + return m_bmp == screen; + } + + gfx::Rect getClipBounds() OVERRIDE { + return gfx::Rect( + m_bmp->cl, + m_bmp->ct, + m_bmp->cr - m_bmp->cl, + m_bmp->cb - m_bmp->ct); + } + + void setClipBounds(const gfx::Rect& rc) OVERRIDE { + set_clip_rect(m_bmp, + rc.x, + rc.y, + rc.x+rc.w-1, + rc.y+rc.h-1); + } + + bool intersectClipRect(const gfx::Rect& rc) OVERRIDE { + add_clip_rect(m_bmp, + rc.x, + rc.y, + rc.x+rc.w-1, + rc.y+rc.h-1); + + return + (m_bmp->cl < m_bmp->cr && + m_bmp->ct < m_bmp->cb); + } + LockedSurface* lock() OVERRIDE { acquire_bitmap(m_bmp); return this; @@ -101,6 +143,95 @@ namespace she { clear_to_color(m_bmp, 0); } + uint8_t* getData(int x, int y) OVERRIDE { + switch (bitmap_color_depth(m_bmp)) { + case 8: return (uint8_t*)(((uint8_t*)bmp_write_line(m_bmp, y)) + x); + case 15: + case 16: return (uint8_t*)(((uint16_t*)bmp_write_line(m_bmp, y)) + x); + case 24: return (uint8_t*)(((uint8_t*)bmp_write_line(m_bmp, y)) + x*3); + case 32: return (uint8_t*)(((uint32_t*)bmp_write_line(m_bmp, y)) + x); + } + return NULL; + } + + void getFormat(SurfaceFormatData* formatData) OVERRIDE { + formatData->format = kRgbaSurfaceFormat; + formatData->bitsPerPixel = bitmap_color_depth(m_bmp); + + switch (formatData->bitsPerPixel) { + case 8: + formatData->redShift = 0; + formatData->greenShift = 0; + formatData->blueShift = 0; + formatData->alphaShift = 0; + formatData->redMask = 0; + formatData->greenMask = 0; + formatData->blueMask = 0; + formatData->alphaMask = 0; + break; + case 15: + formatData->redShift = _rgb_r_shift_15; + formatData->greenShift = _rgb_g_shift_15; + formatData->blueShift = _rgb_b_shift_15; + formatData->alphaShift = 0; + formatData->redMask = 31 << _rgb_r_shift_15; + formatData->greenMask = 31 << _rgb_g_shift_15; + formatData->blueMask = 31 << _rgb_b_shift_15; + formatData->alphaMask = 0; + break; + case 16: + formatData->redShift = _rgb_r_shift_16; + formatData->greenShift = _rgb_g_shift_16; + formatData->blueShift = _rgb_b_shift_16; + formatData->alphaShift = 0; + formatData->redMask = 31 << _rgb_r_shift_16; + formatData->greenMask = 63 << _rgb_g_shift_16; + formatData->blueMask = 31 << _rgb_b_shift_16; + formatData->alphaMask = 0; + break; + case 24: + formatData->redShift = _rgb_r_shift_24; + formatData->greenShift = _rgb_g_shift_24; + formatData->blueShift = _rgb_b_shift_24; + formatData->alphaShift = 0; + formatData->redMask = 255 << _rgb_r_shift_24; + formatData->greenMask = 255 << _rgb_g_shift_24; + formatData->blueMask = 255 << _rgb_b_shift_24; + formatData->alphaMask = 0; + break; + case 32: + formatData->redShift = _rgb_r_shift_32; + formatData->greenShift = _rgb_g_shift_32; + formatData->blueShift = _rgb_b_shift_32; + formatData->alphaShift = _rgb_a_shift_32; + formatData->redMask = 255 << _rgb_r_shift_32; + formatData->greenMask = 255 << _rgb_g_shift_32; + formatData->blueMask = 255 << _rgb_b_shift_32; + formatData->alphaMask = 255 << _rgb_a_shift_32; + break; + } + } + + void drawHLine(she::Color color, int x, int y, int w) OVERRIDE { + hline(m_bmp, x, y, x+w-1, to_allegro(color)); + } + + void drawVLine(she::Color color, int x, int y, int h) OVERRIDE { + vline(m_bmp, x, y, y+h-1, to_allegro(color)); + } + + void drawLine(she::Color color, const gfx::Point& a, const gfx::Point& b) OVERRIDE { + line(m_bmp, a.x, a.y, b.x, b.y, to_allegro(color)); + } + + void drawRect(she::Color color, const gfx::Rect& rc) OVERRIDE { + rect(m_bmp, rc.x, rc.y, rc.x+rc.w-1, rc.y+rc.h-1, to_allegro(color)); + } + + void fillRect(she::Color color, const gfx::Rect& rc) OVERRIDE { + rectfill(m_bmp, rc.x, rc.y, rc.x+rc.w-1, rc.y+rc.h-1, to_allegro(color)); + } + void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const OVERRIDE { ASSERT(m_bmp); ASSERT(dest); @@ -113,11 +244,38 @@ namespace she { width, height); } + void drawSurface(const LockedSurface* src, int dstx, int dsty) OVERRIDE { + draw_sprite(m_bmp, static_cast(src)->m_bmp, dstx, dsty); + } + void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) OVERRIDE { set_alpha_blender(); draw_trans_sprite(m_bmp, static_cast(src)->m_bmp, dstx, dsty); } + void drawChar(Font* sheFont, she::Color fg, she::Color bg, int x, int y, int chr) OVERRIDE { + FONT* allegFont = reinterpret_cast(sheFont->nativeHandle()); + + allegFont->vtable->render_char(allegFont, chr, + to_allegro(fg), + to_allegro(bg), + m_bmp, x, y); + } + + void drawString(Font* sheFont, she::Color fg, she::Color bg, int x, int y, const std::string& str) OVERRIDE { + FONT* allegFont = reinterpret_cast(sheFont->nativeHandle()); + base::utf8_const_iterator it(str.begin()), end(str.end()); + int length = 0; + int sysfg = to_allegro(fg); + int sysbg = to_allegro(bg); + + while (it != end) { + allegFont->vtable->render_char(allegFont, *it, sysfg, sysbg, m_bmp, x, y); + x += sheFont->charWidth(*it); + ++it; + } + } + private: BITMAP* m_bmp; DestroyFlag m_destroy; diff --git a/src/she/color.h b/src/she/color.h new file mode 100644 index 000000000..ac1b51f55 --- /dev/null +++ b/src/she/color.h @@ -0,0 +1,44 @@ +// SHE library +// Copyright (C) 2012-2014 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_COLOR_H_INCLUDED +#define SHE_COLOR_H_INCLUDED +#pragma once + +namespace she { + + typedef uint32_t Color; + typedef uint8_t ColorComponent; + + static const int ColorRShift = 0; + static const int ColorGShift = 8; + static const int ColorBShift = 16; + static const int ColorAShift = 24; + + static const Color ColorNone = Color(0); + + inline Color rgba(ColorComponent r, ColorComponent g, ColorComponent b, ColorComponent a = 255) { + return Color((r << ColorRShift) | + (g << ColorGShift) | + (b << ColorBShift) | + (a << ColorAShift)); + } + + inline ColorComponent getr(Color c) { return (c >> ColorRShift) & 0xff; } + inline ColorComponent getg(Color c) { return (c >> ColorGShift) & 0xff; } + inline ColorComponent getb(Color c) { return (c >> ColorBShift) & 0xff; } + inline ColorComponent geta(Color c) { return (c >> ColorAShift) & 0xff; } + + inline Color setr(Color c, ColorComponent v) { return Color((c & ~ColorRShift) | (v << ColorRShift)); } + inline Color setg(Color c, ColorComponent v) { return Color((c & ~ColorGShift) | (v << ColorGShift)); } + inline Color setb(Color c, ColorComponent v) { return Color((c & ~ColorBShift) | (v << ColorBShift)); } + inline Color seta(Color c, ColorComponent v) { return Color((c & ~ColorAShift) | (v << ColorAShift)); } + + inline bool is_transparent(Color c) { return geta(c) == 0; } + +} // namespace she + +#endif // SHE_COLOR_H_INCLUDED diff --git a/src/she/locked_surface.h b/src/she/locked_surface.h index f925a185f..4b21acc72 100644 --- a/src/she/locked_surface.h +++ b/src/she/locked_surface.h @@ -8,15 +8,38 @@ #define SHE_LOCKED_SURFACE_H_INCLUDED #pragma once +#include "gfx/fwd.h" +#include "she/color.h" +#include "she/surface_format.h" + +#include + namespace she { + class Font; + class LockedSurface { public: virtual ~LockedSurface() { } virtual void unlock() = 0; virtual void clear() = 0; + + virtual uint8_t* getData(int x, int y) = 0; + virtual void getFormat(SurfaceFormatData* formatData) = 0; + + virtual void drawHLine(she::Color color, int x, int y, int w) = 0; + virtual void drawVLine(she::Color color, int x, int y, int h) = 0; + virtual void drawLine(she::Color color, const gfx::Point& a, const gfx::Point& b) = 0; + + virtual void drawRect(she::Color color, const gfx::Rect& rc) = 0; + virtual void fillRect(she::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 drawSurface(const LockedSurface* src, int dstx, int dsty) = 0; virtual void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) = 0; + + virtual void drawChar(Font* font, she::Color fg, she::Color bg, int x, int y, int chr) = 0; + virtual void drawString(Font* font, she::Color fg, she::Color bg, int x, int y, const std::string& str) = 0; }; } // namespace she diff --git a/src/she/surface.h b/src/she/surface.h index 00a9bdd28..47ed927d6 100644 --- a/src/she/surface.h +++ b/src/she/surface.h @@ -8,6 +8,8 @@ #define SHE_SURFACE_H_INCLUDED #pragma once +#include "gfx/fwd.h" + namespace she { class LockedSurface; @@ -18,6 +20,12 @@ namespace she { virtual void dispose() = 0; virtual int width() const = 0; virtual int height() const = 0; + virtual bool isDirectToScreen() const = 0; + + virtual gfx::Rect getClipBounds() = 0; + virtual void setClipBounds(const gfx::Rect& rc) = 0; + virtual bool intersectClipRect(const gfx::Rect& rc) = 0; + virtual LockedSurface* lock() = 0; virtual void applyScale(int scaleFactor) = 0; virtual void* nativeHandle() = 0; diff --git a/src/she/surface_format.h b/src/she/surface_format.h new file mode 100644 index 000000000..7f21bfeb5 --- /dev/null +++ b/src/she/surface_format.h @@ -0,0 +1,32 @@ +// 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_SURFACE_FORMAT_H_INCLUDED +#define SHE_SURFACE_FORMAT_H_INCLUDED +#pragma once + +namespace she { + + enum SurfaceFormat { + kRgbaSurfaceFormat, + }; + + struct SurfaceFormatData { + SurfaceFormat format; + uint32_t bitsPerPixel; + uint32_t redShift; + uint32_t greenShift; + uint32_t blueShift; + uint32_t alphaShift; + uint32_t redMask; + uint32_t greenMask; + uint32_t blueMask; + uint32_t alphaMask; + }; + +} // namespace she + +#endif diff --git a/src/ui/color.h b/src/ui/color.h index 326790bc8..bcc53b470 100644 --- a/src/ui/color.h +++ b/src/ui/color.h @@ -8,6 +8,8 @@ #define UI_COLOR_H_INCLUDED #pragma once +#include "she/color.h" + namespace ui { typedef uint32_t Color; diff --git a/src/ui/draw.h b/src/ui/draw.h index f9ec851b7..833d75052 100644 --- a/src/ui/draw.h +++ b/src/ui/draw.h @@ -8,16 +8,9 @@ #define UI_DRAW_H_INCLUDED #pragma once -#include "gfx/rect.h" #include "gfx/region.h" -#include "ui/base.h" -#include "ui/color.h" -struct BITMAP; - -// TODO all these functions are deprecated and must be replaced by Graphics methods. - -namespace ui { +namespace ui { // TODO all these functions are deprecated and must be replaced by Graphics methods. void _move_region(const gfx::Region& region, int dx, int dy); diff --git a/src/ui/graphics.cpp b/src/ui/graphics.cpp index 543600873..e92b5afe3 100644 --- a/src/ui/graphics.cpp +++ b/src/ui/graphics.cpp @@ -15,18 +15,25 @@ #include "gfx/rect.h" #include "gfx/region.h" #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/theme.h" -#include -#include +namespace { + + inline she::Color to_she(ui::Color color) { + return (she::Color)color; + } + +} namespace ui { -Graphics::Graphics(BITMAP* bmp, int dx, int dy) - : m_bmp(bmp) +Graphics::Graphics(she::Surface* surface, int dx, int dy) + : m_surface(surface) , m_dx(dx) , m_dy(dy) { @@ -38,74 +45,49 @@ Graphics::~Graphics() gfx::Rect Graphics::getClipBounds() const { - return gfx::Rect(m_bmp->cl-m_dx, - m_bmp->ct-m_dy, - m_bmp->cr-m_bmp->cl, - m_bmp->cb-m_bmp->ct); + return m_surface->getClipBounds().offset(-m_dx, -m_dy); } void Graphics::setClipBounds(const gfx::Rect& rc) { - set_clip_rect(m_bmp, - m_dx+rc.x, - m_dy+rc.y, - m_dx+rc.x+rc.w-1, - m_dy+rc.y+rc.h-1); + m_surface->setClipBounds(gfx::Rect(rc).offset(m_dx, m_dy)); } bool Graphics::intersectClipRect(const gfx::Rect& rc) { - add_clip_rect(m_bmp, - m_dx+rc.x, - m_dy+rc.y, - m_dx+rc.x+rc.w-1, - m_dy+rc.y+rc.h-1); - - return (m_bmp->cl < m_bmp->cr && - m_bmp->ct < m_bmp->cb); + return m_surface->intersectClipRect(gfx::Rect(rc).offset(m_dx, m_dy)); } void Graphics::drawHLine(ui::Color color, int x, int y, int w) { - hline(m_bmp, - m_dx+x, - m_dy+y, - m_dx+x+w-1, to_system(color)); + she::ScopedSurfaceLock dst(m_surface); + dst->drawHLine(to_she(color), m_dx+x, m_dy+y, w); } void Graphics::drawVLine(ui::Color color, int x, int y, int h) { - vline(m_bmp, - m_dx+x, - m_dy+y, - m_dy+y+h-1, to_system(color)); + she::ScopedSurfaceLock dst(m_surface); + dst->drawVLine(to_she(color), m_dx+x, m_dy+y, h); } void Graphics::drawLine(ui::Color color, const gfx::Point& a, const gfx::Point& b) { - line(m_bmp, - m_dx+a.x, - m_dy+a.y, - m_dx+b.x, - m_dy+b.y, to_system(color)); + she::ScopedSurfaceLock dst(m_surface); + dst->drawLine(to_she(color), + gfx::Point(m_dx+a.x, m_dy+a.y), + gfx::Point(m_dx+b.x, m_dy+b.y)); } void Graphics::drawRect(ui::Color color, const gfx::Rect& rc) { - rect(m_bmp, - m_dx+rc.x, - m_dy+rc.y, - m_dx+rc.x+rc.w-1, - m_dy+rc.y+rc.h-1, to_system(color)); + she::ScopedSurfaceLock dst(m_surface); + dst->drawRect(to_she(color), gfx::Rect(rc).offset(m_dx, m_dy)); } void Graphics::fillRect(ui::Color color, const gfx::Rect& rc) { - rectfill(m_bmp, - m_dx+rc.x, - m_dy+rc.y, - m_dx+rc.x+rc.w-1, - m_dy+rc.y+rc.h-1, to_system(color)); + she::ScopedSurfaceLock dst(m_surface); + dst->fillRect(to_she(color), gfx::Rect(rc).offset(m_dx, m_dy)); } void Graphics::fillRegion(ui::Color color, const gfx::Region& rgn) @@ -128,21 +110,23 @@ void Graphics::fillAreaBetweenRects(ui::Color color, void Graphics::drawSurface(she::Surface* surface, int x, int y) { - BITMAP* sprite = reinterpret_cast(surface->nativeHandle()); - draw_sprite(m_bmp, sprite, m_dx+x, m_dy+y); + she::ScopedSurfaceLock src(surface); + she::ScopedSurfaceLock dst(m_surface); + dst->drawSurface(src, m_dx+x, m_dy+y); } void Graphics::drawRgbaSurface(she::Surface* surface, int x, int y) { - BITMAP* sprite = reinterpret_cast(surface->nativeHandle()); - - set_alpha_blender(); - draw_trans_sprite(m_bmp, sprite, m_dx+x, m_dy+y); + she::ScopedSurfaceLock src(surface); + she::ScopedSurfaceLock dst(m_surface); + dst->drawRgbaSurface(src, m_dx+x, m_dy+y); } -void Graphics::blit(BITMAP* src, int srcx, int srcy, int dstx, int dsty, int w, int h) +void Graphics::blit(she::Surface* srcSurface, int srcx, int srcy, int dstx, int dsty, int w, int h) { - ::blit(src, m_bmp, srcx, srcy, 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); } void Graphics::setFont(she::Font* font) @@ -152,40 +136,23 @@ void Graphics::setFont(she::Font* font) void Graphics::drawChar(int chr, Color fg, Color bg, int x, int y) { - FONT* font = reinterpret_cast(m_font->nativeHandle()); - - font->vtable->render_char(font, chr, - to_system(fg), - to_system(bg), - m_bmp, m_dx+x, m_dy+y); + she::ScopedSurfaceLock dst(m_surface); + dst->drawChar(m_font, to_she(fg), to_she(bg), m_dx+x, m_dy+y, chr); } -void Graphics::drawString(const std::string& str, Color fg, Color bg, bool fillbg, const gfx::Point& pt) +void Graphics::drawString(const std::string& str, Color fg, Color bg, const gfx::Point& pt) { - FONT* font = reinterpret_cast(m_font->nativeHandle()); + she::ScopedSurfaceLock dst(m_surface); + dst->drawString(m_font, to_she(fg), to_she(bg), m_dx+pt.x, m_dy+pt.y, str); +} + +void Graphics::drawUIString(const std::string& str, Color fg, Color bg, const gfx::Point& pt) +{ + she::ScopedSurfaceLock dst(m_surface); base::utf8_const_iterator it(str.begin()), end(str.end()); int length = 0; int x = m_dx+pt.x; int y = m_dy+pt.y; - int sysfg = to_system(fg); - int sysbg = (fillbg ? to_system(bg): -1); - - while (it != end) { - font->vtable->render_char(font, *it, sysfg, sysbg, m_bmp, x, y); - x += m_font->charWidth(*it); - ++it; - } -} - -void Graphics::drawUIString(const std::string& str, Color fg, Color bg, bool fillbg, const gfx::Point& pt) -{ - FONT* font = reinterpret_cast(m_font->nativeHandle()); - base::utf8_const_iterator it(str.begin()), end(str.end()); - int length = 0; - int x = m_dx+pt.x; - int y = m_dy+pt.y; - int sysfg = to_system(fg); - int sysbg = (fillbg ? to_system(bg): -1); int underscored_x; int underscored_w = -1; @@ -197,18 +164,15 @@ void Graphics::drawUIString(const std::string& str, Color fg, Color bg, bool fil underscored_w = m_font->charWidth(*it); } } - - font->vtable->render_char(font, *it, sysfg, sysbg, m_bmp, x, y); - + dst->drawChar(m_font, to_she(fg), to_she(bg), x, y, *it); x += m_font->charWidth(*it); ++it; } if (underscored_w > 0) { y += m_font->height(); - rectfill(m_bmp, underscored_x, y, - underscored_x+underscored_w-1, - y+jguiscale()-1, sysfg); + dst->fillRect(to_she(fg), + gfx::Rect(underscored_x, y, underscored_w, jguiscale())); } } @@ -255,7 +219,6 @@ gfx::Size Graphics::fitString(const std::string& str, int maxWidth, int align) gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, Color fg, Color bg, const gfx::Rect& rc, int align, bool draw) { - FONT* font = reinterpret_cast(getFont()->nativeHandle()); gfx::Point pt(0, rc.y); if ((align & (JI_MIDDLE | JI_BOTTOM)) != 0) { @@ -287,7 +250,7 @@ gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, Color fg, Color // If we have already a word to print (old_end != npos), and // we are out of the available width (rc.w) using the new "end", if ((old_end != std::string::npos) && - (pt.x+measureUIString(str.substr(beg, end-beg)).w > rc.w)) { + (pt.x+m_font->textLength(str.substr(beg, end-beg).c_str()) > rc.w)) { // We go back to the "old_end" and paint from "beg" to "end" end = old_end; break; @@ -312,7 +275,9 @@ gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, Color fg, Color // Get the entire line to be painted line = str.substr(beg, end-beg); - gfx::Size lineSize = measureUIString(line); + gfx::Size lineSize( + m_font->textLength(line.c_str()), + m_font->height()); calculatedSize.w = MAX(calculatedSize.w, lineSize.w); // Render the text @@ -325,7 +290,7 @@ gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, Color fg, Color else xout = pt.x; - textout_ex(m_bmp, font, line.c_str(), m_dx+xout, m_dy+pt.y, to_system(fg), to_system(bg)); + drawString(line, fg, bg, gfx::Point(xout, pt.y)); if (!is_transparent(bg)) fillAreaBetweenRects(bg, @@ -351,7 +316,7 @@ gfx::Size Graphics::doUIStringAlgorithm(const std::string& str, Color fg, Color // ScreenGraphics ScreenGraphics::ScreenGraphics() - : Graphics(screen, 0, 0) + : Graphics(she::instance()->defaultDisplay()->getSurface(), 0, 0) { setFont(CurrentTheme::get()->default_font); } diff --git a/src/ui/graphics.h b/src/ui/graphics.h index 2e2b60f6f..46286a9e6 100644 --- a/src/ui/graphics.h +++ b/src/ui/graphics.h @@ -17,8 +17,6 @@ #include -struct BITMAP; - namespace gfx { class Region; } @@ -33,10 +31,10 @@ namespace ui { // Class to render a widget in the screen. class Graphics { public: - Graphics(BITMAP* bmp, int dx, int dy); + Graphics(she::Surface* surface, int dx, int dy); ~Graphics(); - BITMAP* getInternalBitmap() { return m_bmp; } + she::Surface* getInternalSurface() { return m_surface; } int getInternalDeltaX() { return m_dx; } int getInternalDeltaY() { return m_dy; } @@ -57,7 +55,7 @@ namespace ui { void drawSurface(she::Surface* surface, int x, int y); void drawRgbaSurface(she::Surface* surface, int x, int y); - void blit(BITMAP* src, int srcx, int srcy, int dstx, int dsty, int w, int h); + void blit(she::Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h); // ====================================================================== // FONT & TEXT @@ -67,8 +65,8 @@ namespace ui { she::Font* getFont() { return m_font; } void drawChar(int chr, Color fg, Color bg, int x, int y); - void drawString(const std::string& str, Color fg, Color bg, bool fillbg, const gfx::Point& pt); - void drawUIString(const std::string& str, Color fg, Color bg, bool fillbg, const gfx::Point& pt); + void drawString(const std::string& str, Color fg, Color bg, const gfx::Point& pt); + void drawUIString(const std::string& str, Color fg, Color bg, const gfx::Point& pt); void drawAlignedUIString(const std::string& str, Color fg, Color bg, const gfx::Rect& rc, int align); gfx::Size measureChar(int chr); @@ -79,7 +77,7 @@ namespace ui { private: gfx::Size doUIStringAlgorithm(const std::string& str, Color fg, Color bg, const gfx::Rect& rc, int align, bool draw); - BITMAP* m_bmp; + she::Surface* m_surface; int m_dx; int m_dy; gfx::Rect m_clipBounds; diff --git a/src/ui/theme.cpp b/src/ui/theme.cpp index c72f388ff..e0fafc7af 100644 --- a/src/ui/theme.cpp +++ b/src/ui/theme.cpp @@ -202,7 +202,7 @@ void drawTextBox(Graphics* g, Widget* widget, else // Left align xout = x; - g->drawUIString(beg, fg, bg, true, gfx::Point(xout, y)); + g->drawUIString(beg, fg, bg, gfx::Point(xout, y)); g->fillAreaBetweenRects(bg, gfx::Rect(x1, y, x2 - x1, textheight), gfx::Rect(xout, y, len, textheight)); diff --git a/src/ui/theme.h b/src/ui/theme.h index ad9858a60..8f2cdc008 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -11,8 +11,6 @@ #include "ui/base.h" #include "ui/cursor_type.h" -struct BITMAP; - namespace gfx { class Region; } diff --git a/src/ui/widget.cpp b/src/ui/widget.cpp index 747d53663..6f8299a75 100644 --- a/src/ui/widget.cpp +++ b/src/ui/widget.cpp @@ -11,7 +11,11 @@ #endif #include "base/memory.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/intern.h" #include "ui/ui.h" @@ -943,7 +947,8 @@ void Widget::paint(Graphics* graphics, const gfx::Region& drawRegion) widget->getDrawableRegion(region, kCutTopWindows); region.createIntersection(region, drawRegion); - Graphics graphics2(graphics->getInternalBitmap(), + Graphics graphics2( + graphics->getInternalSurface(), widget->getBounds().x, widget->getBounds().y); graphics2.setFont(widget->getFont()); @@ -1055,38 +1060,45 @@ void Widget::scrollRegion(const Region& region, int dx, int dy) flushRedraw(); } -class DeleteGraphicsAndBitmap { +class DeleteGraphicsAndSurface { public: - DeleteGraphicsAndBitmap(const gfx::Rect& clip, BITMAP* bmp) - : m_pt(clip.getOrigin()), m_bmp(bmp) { + DeleteGraphicsAndSurface(const gfx::Rect& clip, she::Surface* surface) + : m_pt(clip.getOrigin()), m_surface(surface) { } void operator()(Graphics* graphics) { - blit(m_bmp, ji_screen, 0, 0, m_pt.x, m_pt.y, m_bmp->w, m_bmp->h); - destroy_bitmap(m_bmp); + { + she::ScopedSurfaceLock src(m_surface); + she::ScopedSurfaceLock dst(she::instance()->defaultDisplay()->getSurface()); + src->blitTo(dst, 0, 0, m_pt.x, m_pt.y, + m_surface->width(), m_surface->height()); + } + m_surface->dispose(); delete graphics; } private: gfx::Point m_pt; - BITMAP* m_bmp; + she::Surface* m_surface; }; GraphicsPtr Widget::getGraphics(const gfx::Rect& clip) { GraphicsPtr graphics; + she::Surface* surface; + she::Surface* defaultSurface = she::instance()->defaultDisplay()->getSurface(); - if (m_doubleBuffered && ji_screen == screen) { - BITMAP* bmp = create_bitmap_ex( - bitmap_color_depth(ji_screen), clip.w, clip.h); - - graphics.reset(new Graphics(bmp, -clip.x, -clip.y), - DeleteGraphicsAndBitmap(clip, bmp)); + // In case of double-buffering, we need to create the temporary + // buffer only if the default surface is the screen. + if (m_doubleBuffered && defaultSurface->isDirectToScreen()) { + surface = she::instance()->createSurface(clip.w, clip.h); + graphics.reset(new Graphics(surface, -clip.x, -clip.y), + DeleteGraphicsAndSurface(clip, surface)); } - // Paint directly on ji_screen (in this case "ji_screen" can be - // the screen or a memory bitmap). + // In other case, we can draw directly onto the screen. else { - graphics.reset(new Graphics(ji_screen, getBounds().x, getBounds().y)); + surface = defaultSurface; + graphics.reset(new Graphics(surface, getBounds().x, getBounds().y)); } graphics->setFont(getFont()); diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 5d5ef5a40..87e5bdf32 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -581,7 +581,7 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit) moveableRegion.createIntersection(oldDrawableRegion, reg1); // Move the window's graphics - Graphics g(ji_screen, 0, 0); + ScreenGraphics g; jmouse_hide(); { IntersectClip clip(&g, man_pos);