void MaskedIcon::Draw(Canvas &canvas, PixelScalar x, PixelScalar y) const { assert(IsDefined()); #ifdef ENABLE_OPENGL if (size.cx == 0) /* hack: do the postponed layout calcuation now */ const_cast<MaskedIcon *>(this)->CalculateLayout((bool)size.cy); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLEnable scope(GL_TEXTURE_2D); const GLBlend blend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLTexture &texture = *bitmap.GetNative(); texture.Bind(); texture.Draw(x - origin.x, y - origin.y); #else #ifdef USE_GDI /* our icons are monochrome bitmaps, and GDI uses current colors of the destination HDC when blitting from a monochrome HDC */ canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundColor(COLOR_WHITE); #endif canvas.CopyOr(x - origin.x, y - origin.y, size.cx, size.cy, bitmap, 0, 0); canvas.CopyAnd(x - origin.x, y - origin.y, size.cx, size.cy, bitmap, size.cx, 0); #endif }
void TransparentRendererCache::CopyAndTo(Canvas &canvas, const WindowProjection &projection) const { if (empty) return; canvas.CopyAnd(0, 0, projection.GetScreenWidth(), projection.GetScreenHeight(), buffer, 0, 0); }
void TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle, const TCHAR *caption, const PixelRect &rc, const Bitmap *bmp, const bool isDown, bool inverse) { PixelRect rcTextFinal = rc; const UPixelScalar buttonheight = rc.bottom - rc.top; const PixelSize text_size = canvas.CalcTextSize(caption); const int textwidth = text_size.cx; const int textheight = text_size.cy; UPixelScalar textheightoffset = 0; if (textwidth > (rc.right - rc.left)) // assume 2 lines textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2); else textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2); rcTextFinal.top += textheightoffset; canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor()); if (bmp != NULL) { const PixelSize bitmap_size = bmp->GetSize(); const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2; const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2; if (inverse) // black background canvas.CopyNotOr(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); else canvas.CopyAnd(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); } else { #ifndef USE_GDI if (IsDithered()) CaptionStyle |= DT_UNDERLINE; #endif canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle); } }
void TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle, const TCHAR *caption, const PixelRect &rc, const Bitmap *bmp, const bool isDown, bool inverse) { PixelRect rcTextFinal = rc; const UPixelScalar buttonheight = rc.bottom - rc.top; const PixelSize text_size = canvas.CalcTextSize(caption); const int textwidth = text_size.cx; const int textheight = text_size.cy; UPixelScalar textheightoffset = 0; if (textwidth > (rc.right - rc.left)) // assume 2 lines textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2); else textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2); rcTextFinal.top += textheightoffset; canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor()); if (bmp != nullptr) { const PixelSize bitmap_size = bmp->GetSize(); const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2; const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2; #ifdef ENABLE_OPENGL if (inverse) { OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); /* invert the texture color */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* copy the texture alpha */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); } else /* simple copy */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLEnable scope(GL_TEXTURE_2D); const GLBlend blend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLTexture &texture = *bmp->GetNative(); texture.Bind(); texture.Draw(rc.left + offsetx, rc.top + offsety); #else if (inverse) // black background canvas.CopyNotOr(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); else canvas.CopyAnd(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); #endif } else { #ifndef USE_GDI if (IsDithered()) CaptionStyle |= DT_UNDERLINE; #endif canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle); } }
void PaintTask(Canvas &canvas, const WindowProjection &projection, const OrderedTask &task, const GeoPoint &location, const MapSettings &settings_map, const TaskLook &task_look, const AirspaceLook &airspace_look, const RasterTerrain *terrain, const Airspaces *airspaces, bool fai_sectors, int highlight_index) { BackgroundRenderer background; background.SetTerrain(terrain); background.Draw(canvas, projection, settings_map.terrain); if (airspaces != NULL) { AirspaceRenderer airspace_renderer(airspace_look); airspace_renderer.SetAirspaces(airspaces); #ifndef ENABLE_OPENGL BufferCanvas stencil_canvas; stencil_canvas.Create(canvas); #endif airspace_renderer.Draw(canvas, #ifndef ENABLE_OPENGL stencil_canvas, #endif projection, settings_map.airspace); } #ifdef ENABLE_OPENGL /* desaturate the map background, to focus on the task */ canvas.FadeToWhite(0xc0); #endif if (fai_sectors && IsFAITriangleApplicable(task)) { static constexpr Color fill_color = COLOR_YELLOW; #if defined(ENABLE_OPENGL) || defined(USE_MEMORY_CANVAS) #ifdef ENABLE_OPENGL const ScopeAlphaBlend alpha_blend; #endif canvas.Select(Brush(fill_color.WithAlpha(40))); canvas.Select(Pen(1, COLOR_BLACK.WithAlpha(80))); RenderFAISectors(canvas, projection, task); #else BufferCanvas buffer_canvas; buffer_canvas.Create(canvas); buffer_canvas.ClearWhite(); #ifdef HAVE_HATCHED_BRUSH buffer_canvas.Select(airspace_look.brushes[3]); buffer_canvas.SetTextColor(fill_color); buffer_canvas.SetBackgroundColor(COLOR_WHITE); #else buffer_canvas.Select(Brush(fill_color)); #endif buffer_canvas.SelectNullPen(); RenderFAISectors(buffer_canvas, projection, task); canvas.CopyAnd(buffer_canvas); canvas.SelectHollowBrush(); canvas.SelectBlackPen(); RenderFAISectors(canvas, projection, task); #endif } OZRenderer ozv(task_look, airspace_look, settings_map.airspace); TaskPointRenderer tpv(canvas, projection, task_look, task.GetTaskProjection(), ozv, false, TaskPointRenderer::NONE, location); TaskRenderer dv(tpv, projection.GetScreenBounds()); dv.Draw(task); // highlight a task point if (highlight_index >= 0 && highlight_index < (int) task.TaskSize()) { /* TODO: clumsy way of highlighting. maybe it should be done by * painting the task point with a different pen and brush, * e.g. red, 4px wide */ auto pt = projection.GeoToScreen(task.GetPoint(highlight_index). GetLocation()); canvas.Select(task_look.highlight_pen); canvas.DrawLine(pt.x - 7, pt.y - 7, pt.x + 7, pt.y + 7); canvas.DrawLine(pt.x + 7, pt.y - 7, pt.x - 7, pt.y + 7); } }