clan::Image App::get_stencil(clan::Canvas &canvas, clan::Rect rect) { canvas.flush(); // For an unknown reason, stencil reads should be a multiple of 32 rect.left = 32 * ((rect.left + 31) / 32); rect.top = 32 * ((rect.top + 31) / 32); rect.right = 32 * ((rect.right + 31) / 32); rect.bottom = 32 * ((rect.bottom + 31) / 32); int rect_width = rect.get_width(); int rect_height = rect.get_height(); std::vector<unsigned char> buffer; buffer.resize(rect_width * rect_height); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ROW_LENGTH, rect_width); glPixelStorei(GL_PACK_SKIP_PIXELS, 0); glPixelStorei(GL_PACK_SKIP_ROWS, 0); glReadBuffer(GL_BACK); if (glClampColor) { #ifdef GL_CLAMP_READ_COLOR glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE); #else glClampColor(clan::GL_CLAMP_READ_COLOR, GL_FALSE); #endif } glReadPixels(rect.left, canvas.get_height()- rect.bottom, rect_width, rect_height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &buffer[0]); clan::PixelBuffer pbuf(rect_width, rect_height, clan::tf_rgba8); unsigned int *pdata = (unsigned int *) pbuf.get_data(); unsigned char *rdata = &buffer[0]; for (int ycnt=0; ycnt < rect_height; ycnt++) { for (int xcnt=0; xcnt < rect_width; xcnt++) { int value = *(rdata++); if (value == 0) { *(pdata++) = 0xFF005500; } else { value = value * 16; value = 0xFF000000 | value | (value << 8) | (value << 16); *(pdata++) = value; } } } pbuf.flip_vertical(); return clan::Image(canvas, pbuf, pbuf.get_size()); }
void Text::draw(clan::Canvas &canvas, const clan::Rect &rect) { int out_draw_offset; std::string text = build_text(canvas, rect.get_width(), scroller_xoffset, out_draw_offset); int ypos = rect.bottom - ((rect.get_height() - font_metrics.get_ascent())/2); // Remove the next line to observe how the clipping works canvas.set_cliprect(rect); font.draw_text(canvas, rect.left - out_draw_offset, ypos, text); canvas.reset_cliprect(); }
clan::Point GridObject::get_dist(clan::ComponentAnchorPoint ap, clan::Point p, clan::Rect boundary) { int bw = boundary.get_width(), bh = boundary.get_height(); if (ap == clan::anchor_top_left) { return clan::Point(p.x, p.y); } else if (ap == clan::anchor_top_right) { return clan::Point(bw-p.x, p.y); } else if (ap == clan::anchor_bottom_left) { return clan::Point(p.x, bh-p.y); } else if (ap == clan::anchor_bottom_right) { return clan::Point(bw-p.x, bh-p.y); } return clan::Point(0,0); }
void Viewport::CalculateScreenArea(const clan::GraphicContext& gc, clan::Rect &area, bool apply_camera_offset) { const clan::Rectf &proportions = GetArea(); area.left = (int)floor(proportions.left * gc.get_width()); area.top = (int)floor(proportions.top * gc.get_height()); area.right = (int)ceil(proportions.right * gc.get_width()); area.bottom = (int)ceil(proportions.bottom * gc.get_height()); if (apply_camera_offset) { const CameraPtr &camera = GetCamera(); if (!camera) FSN_EXCEPT(ExCode::InvalidArgument, "Cannot apply camera offset if the viewport has no camera associated with it"); // Viewport offset is the top-left of the viewport in the game-world, // i.e. camera_offset - viewport_size * camera_origin clan::Vec2i viewportOffset = camera->GetPosition() - clan::Vec2f::calc_origin(clan::origin_center, clan::Sizef((float)area.get_width(), (float)area.get_height())); area.translate(viewportOffset); } }