/** * @brief Displays the dialog box on a surface. * @param destination_surface the surface */ void DialogBox::display(Surface* destination_surface) { int x = box_dst_position.get_x(); int y = box_dst_position.get_y(); dialog_surface.fill_with_color(Color::get_black()); if (style == STYLE_WITHOUT_FRAME) { // display a dark rectangle destination_surface->fill_with_color(Color::get_black(), box_dst_position); } else { // display the dialog box box_img.blit(box_src_position, &dialog_surface, box_dst_position); } // display the text for (int i = 0; i < nb_visible_lines; i++) { line_surfaces[i]->display(&dialog_surface); } // display the icon if (icon_number != -1) { Rectangle src_position(0, 0, 16, 16); src_position.set_xy(16 * (icon_number % 10), 16 * (icon_number / 10)); icons_img.blit(src_position, &dialog_surface, icon_dst_position); question_dst_position.set_x(x + 50); } else { question_dst_position.set_x(x + 18); } // display the question arrow if (dialog.is_question() && is_full() && !has_more_lines()) { box_img.blit(question_src_position, &dialog_surface, question_dst_position); } // display the end message arrow if (is_full()) { end_lines_sprite.display(&dialog_surface, x + 103, y + 56); } // final blit dialog_surface.blit(destination_surface); }
/** * \brief Draws a subrectangle of the current frame of this sprite. * \param region The subrectangle to draw, relative to the origin point. * It may be bigger than the frame: in this case it will be clipped. * \param dst_surface The destination surface. * \param dst_position Coordinates on the destination surface. * The origin point of the sprite will appear at these coordinates. */ void Sprite::raw_draw_region( const Rectangle& region, Surface& dst_surface, const Rectangle& dst_position) { if (!is_animation_finished() && (blink_delay == 0 || blink_is_sprite_visible)) { get_intermediate_surface().fill_with_color(Color::get_black()); const Rectangle& origin = get_origin(); current_animation->draw( get_intermediate_surface(), origin, current_direction, current_frame); // If the region is bigger than the current frame, clip it. // Otherwise, more than the current frame could be visible. Rectangle src_position(region); src_position.add_xy(origin.get_x(), origin.get_y()); const Rectangle& frame_size = get_size(); if (src_position.get_x() < 0) { src_position.set_width(src_position.get_width() + src_position.get_x()); src_position.set_x(0); } if (src_position.get_x() + src_position.get_width() > frame_size.get_width()) { src_position.set_width(frame_size.get_width() - src_position.get_x()); } if (src_position.get_y() < 0) { src_position.set_height(src_position.get_height() + src_position.get_y()); src_position.set_y(0); } if (src_position.get_y() + src_position.get_height() > frame_size.get_height()) { src_position.set_height(frame_size.get_height() - src_position.get_y()); } if (src_position.get_width() <= 0 || src_position.get_height() <= 0) { // Nothing remains visible. return; } // Calculate the destination coordinates. Rectangle dst_position2(dst_position); dst_position2.add_xy(src_position.get_x(), src_position.get_y()); // Let a space for the part outside the region. dst_position2.add_xy(-origin.get_x(), -origin.get_y()); // Input coordinates were relative to the origin. get_intermediate_surface().draw_region(src_position, dst_surface, dst_position2); } }
/** * \brief Redraws the text surface in the case of a bitmap font. * * This function is called when there is a change. */ void TextSurface::rebuild_bitmap() { // First count the number of characters in the UTF-8 string. int num_chars = 0; for (unsigned i = 0; i < text.size(); i++) { char current_char = text[i]; if ((current_char & 0xE0) == 0xC0) { // This character uses two bytes. ++i; } ++num_chars; } // Determine the letter size from the surface size. Surface& bitmap = *fonts[font_id].bitmap; const Rectangle& bitmap_size = bitmap.get_size(); int char_width = bitmap_size.get_width() / 128; int char_height = bitmap_size.get_height() / 16; surface = new Surface(char_width * num_chars, char_height); surface->set_transparency_color(bitmap.get_transparency_color()); // Traverse the string again to draw the characters. Rectangle dst_position(0, 0); for (unsigned i = 0; i < text.size(); i++) { char first_byte = text[i]; Rectangle src_position(0, 0, char_width, char_height); if ((first_byte & 0xE0) != 0xC0) { // This character uses one byte. src_position.set_xy(first_byte * char_width, 0); } else { // This character uses two bytes. ++i; char second_byte = text[i]; uint16_t code_point = ((first_byte & 0x1F) << 6) | (second_byte & 0x3F); src_position.set_xy((code_point % 128) * char_width, (code_point / 128) * char_height); } bitmap.draw_region(src_position, *surface, dst_position); dst_position.add_x(char_width - 1); } }