/* centers source within bounds */ void AdjustRect( Rect *bounds, Rect *source, Rect *destination, short mode) { Rect result; result= *source; switch (mode) { case centerRect: OffsetRect(&result, bounds->left+(RECTANGLE_WIDTH(bounds)-RECTANGLE_WIDTH(source))/2-source->left, bounds->top+(RECTANGLE_HEIGHT(bounds)-RECTANGLE_HEIGHT(source))/2-source->top); break; case alertRect: OffsetRect(&result, bounds->left+(RECTANGLE_WIDTH(bounds)-RECTANGLE_WIDTH(source))/2-source->left, bounds->top+(RECTANGLE_HEIGHT(bounds)-RECTANGLE_HEIGHT(source))/3-source->top); break; default: halt(); } *destination= result; return; }
static void get_device_area_offset( Rect *frame, Point *offset) { GDHandle device= GetMainDevice(); SetPt(offset, (*device)->gdRect.left + RECTANGLE_WIDTH(&(*device)->gdRect)/2, (*device)->gdRect.top + RECTANGLE_HEIGHT(&(*device)->gdRect)/2); SetPt(offset, frame->left + RECTANGLE_WIDTH(frame)/2 - offset->h/DEVICE_AREA_SCALE, frame->top + RECTANGLE_HEIGHT(frame)/2 - offset->v/DEVICE_AREA_SCALE); return; }
/* calculate a new stdState rectangle based on the maximum bounds, positioned on the device which the given window overlaps most */ void build_zoom_rectangle( WindowPtr window, Rect *bounds) { GDHandle device; WStateDataHandle window_state; Rect zoomed, unzoomed; Rect device_bounds; short bias; window_state= (WStateDataHandle) (((CWindowRecord *)window)->dataHandle); zoomed= (*window_state)->stdState; unzoomed= (*window_state)->userState; /* official Apple source sends the title bar along with this rectangle, but that isnÕt useful */ device= MostDevice(&unzoomed); if (!device) device= GetMainDevice(); bias= unzoomed.top-(*((WindowPeek)window)->strucRgn)->rgnBBox.top-1; if (device==GetMainDevice()) bias+= GetMBarHeight(); device_bounds= (*device)->gdRect; InsetRect(&device_bounds, 3, 3); device_bounds.top+= bias; zoomed= *bounds; OffsetRect(&zoomed, unzoomed.left-zoomed.left, unzoomed.top-zoomed.top); if (RECTANGLE_HEIGHT(&zoomed)>RECTANGLE_HEIGHT(&device_bounds)) { zoomed.top= device_bounds.top; zoomed.bottom= device_bounds.bottom; } else { if (zoomed.bottom>device_bounds.bottom) OffsetRect(&zoomed, 0, device_bounds.bottom-zoomed.bottom); if (zoomed.top<device_bounds.top) OffsetRect(&zoomed, 0, device_bounds.top-zoomed.top); } if (RECTANGLE_WIDTH(&zoomed)>RECTANGLE_WIDTH(&device_bounds)) { zoomed.left= device_bounds.left; zoomed.right= device_bounds.right; } else { if (zoomed.right>device_bounds.right) OffsetRect(&zoomed, device_bounds.right-zoomed.right, 0); if (zoomed.left<device_bounds.left) OffsetRect(&zoomed, device_bounds.left-zoomed.left, 0); } (*window_state)->stdState= zoomed; return; }
void _draw_screen_shape_centered( shape_descriptor shape, screen_rectangle *rectangle, short flags) { PixMapHandle pixmap; RGBColor old_fore, old_back; Rect destination, source; short left_offset, top_offset; return; /* Avoid unwanted coloring.. */ GetForeColor(&old_fore); GetBackColor(&old_back); RGBForeColor(&rgb_black); RGBBackColor(&rgb_white); /* Draw the panels... */ pixmap= get_shape_pixmap(shape, FALSE); /* Offset to zero base, and add in x, y */ destination= source= (*pixmap)->bounds; if(flags & _center_horizontal) { left_offset= (RECTANGLE_WIDTH(rectangle)-RECTANGLE_WIDTH(&source))/2; } else { left_offset= 0; } if(flags & _center_vertical) { top_offset= (RECTANGLE_HEIGHT(rectangle)-RECTANGLE_HEIGHT(&source))/2; } else if (flags & _bottom_justified) { top_offset= RECTANGLE_HEIGHT(rectangle)-RECTANGLE_HEIGHT(&destination); } else { top_offset= 0; } OffsetRect(&destination, rectangle->left+left_offset, rectangle->top+top_offset); /* Slam the puppy... */ assert(destination_graphics_port); CopyBits((BitMapPtr) *pixmap, &destination_graphics_port->portBits, // &screen_window->portBits, &source, &destination, srcCopy, (RgnHandle) nil); /* Restore the colors.. */ RGBForeColor(&old_fore); RGBBackColor(&old_back); }
/* -------- code */ void new_log( HWND wp) { struct log_data *new_log; new_log= (struct log_data *) malloc(sizeof(struct log_data)); if(new_log) { new_log->parent= wp; new_log->edit_buffer= (char *)malloc(MAXIMUM_EDIT_LENGTH); new_log->interrupt_safe_buffer[0] = '\0'; if(new_log->edit_buffer) { NMRect bounds; GetClientRect(wp, &bounds); new_log->edit= CreateWindow("EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, RECTANGLE_WIDTH(&bounds), RECTANGLE_HEIGHT(&bounds), wp, NULL, application_instance, NULL); // attach it. new_log->next= first_log; first_log= new_log; } else { free(new_log); } } return; }
/* scale source to fit within bounds with correct aspect ratio and stuff that into destination (centered, of course) */ void ScaleRect( Rect *bounds, Rect *source, Rect *destination) { long horizontal_scale, vertical_scale; Rect new_rectangle; short width, height; /* the largest value will be the constraint (or, the axis we can peg) */ horizontal_scale= (RECTANGLE_WIDTH(source)*LONG_ONE)/RECTANGLE_WIDTH(bounds); vertical_scale= (RECTANGLE_HEIGHT(source)*LONG_ONE)/RECTANGLE_HEIGHT(bounds); if (horizontal_scale>vertical_scale) { width= RECTANGLE_WIDTH(bounds); height= (width*RECTANGLE_HEIGHT(source))/RECTANGLE_WIDTH(source); } else { height= RECTANGLE_HEIGHT(bounds); width= (height*RECTANGLE_WIDTH(source))/RECTANGLE_HEIGHT(source); } SetRect(&new_rectangle, 0, 0, width, height); OffsetRect(&new_rectangle, bounds->left + (RECTANGLE_WIDTH(bounds)-width)/2, bounds->top + (RECTANGLE_HEIGHT(bounds)-height)/2); *destination= new_rectangle; return; }
/* ------------ Local code */ static void add_overhead_thumbnail( FileSpecifier &File) { PicHandle picture; PicHandle preview; RgnHandle clip_region; FontInfo info; short text_x, text_y; short text_length; Str255 temporary; GWorldPtr old_gworld; GDHandle old_device; struct overhead_map_data overhead_data; Rect bounds; AEDesc aeFileSpec; FSSpec *SpecPtr; // Skip all this if there's no nav services to install the preview if(!machine_has_nav_services() || NavLibraryVersion() < kNavServicesVersion_2_0) return; GetGWorld(&old_gworld, &old_device); SetGWorld(world_pixels, (GDHandle) NULL); // Note well. We're using world_pixels to create our thumbnail pict within. // If world_pixels is runing as a postage stamp (low-res + small display space) // Then it is actually smaller than the size we're looking to build a thumbnail // within. But seeing as we're generating pict images and using drawing commands // instead of bit-wise operations. It all works out. /* Create the bounding rectangle */ SetRect(&bounds, 0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); /* Start recording.. */ picture= OpenPicture(&bounds); PaintRect(&bounds); overhead_data.scale= OVERHEAD_MAP_MINIMUM_SCALE; overhead_data.origin.x= local_player->location.x; overhead_data.origin.y= local_player->location.y; overhead_data.half_width= RECTANGLE_WIDTH(&bounds)/2; overhead_data.half_height= RECTANGLE_HEIGHT(&bounds)/2; overhead_data.width= RECTANGLE_WIDTH(&bounds); overhead_data.height= RECTANGLE_HEIGHT(&bounds); overhead_data.mode= _rendering_saved_game_preview; _render_overhead_map(&overhead_data); RGBForeColor(&rgb_black); PenSize(1, 1); TextFont(0); TextFace(normal); TextSize(0); ClosePicture(); // JTP: Add Nav Services style preview SetRect(&bounds, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); preview= OpenPicture(&bounds); SetRect(&bounds, PREVIEW_IMAGE_X, PREVIEW_IMAGE_Y, THUMBNAIL_WIDTH + PREVIEW_IMAGE_X, THUMBNAIL_HEIGHT + PREVIEW_IMAGE_Y); clip_region= NewRgn(); GetClip(clip_region); ClipRect(&bounds); DrawPicture(picture, &bounds); SetClip(clip_region); /* Center the text in the rectangle */ // LP: Classic doesn't have this function #ifdef TARGET_API_MAC_CARBON CopyCStringToPascal(static_world->level_name, temporary); #else strncpy((char *)temporary,static_world->level_name,LEVEL_NAME_LENGTH); c2pstr((char *)temporary); #endif // LP: fix to allow lengths more than 127 bytes (not really necessary, but...) text_length = *ptemporary; TruncText(PREVIEW_WIDTH, (char *)temporary+1, &text_length, smTruncEnd); *ptemporary = text_length; GetFontInfo(&info); text_y= PREVIEW_HEIGHT - info.descent; text_x= PREVIEW_LABEL_X + (PREVIEW_WIDTH-StringWidth(temporary))/2; MoveTo(text_x, text_y); DrawString(temporary); ClosePicture(); // This requires NavServices 2.0, what's the inline check? // From FSS get a AEDesc OSStatus err; SpecPtr = &File.GetSpec(); err = AECreateDesc(typeFSS, SpecPtr, sizeof(FSSpec), &aeFileSpec); HLock((Handle)preview); err = NavCreatePreview(&aeFileSpec, 'PICT', *preview, GetHandleSize((Handle)preview)); HUnlock((Handle)preview); AEDisposeDesc(&aeFileSpec); KillPicture(preview); KillPicture(picture); DisposeRgn(clip_region); SetGWorld(old_gworld, old_device); }
/* This expects a cstring. Draws to the current port*/ void _draw_screen_text( char *text, screen_rectangle *destination, short flags, short font_id, short text_color) { TextSpec old_font; short x, y; RGBColor old_color, new_color; char text_to_draw[256]; assert(font_id>=0 && font_id<NUMBER_OF_INTERFACE_FONTS); GetFont(&old_font); SetFont(&interface_fonts.fonts[font_id]); GetForeColor(&old_color); _get_interface_color(text_color, &new_color); RGBForeColor(&new_color); /* Copy the text to draw.. */ strcpy(text_to_draw, text); /* Check for wrapping, and if it occurs, be recursive... */ if(flags & _wrap_text) { /*еее WHAT IS THE INTERNATIONALIZED WAY OF DETERMINING NON-PRINTING CHARACTERS? IE SPACES? */ short last_non_printing_character; short text_width; short count= 0; text_width= 0; last_non_printing_character= 0; count= 0; while(count<strlen(text_to_draw) && text_width<RECTANGLE_WIDTH(destination)) { text_width+= CharWidth(text_to_draw[count]); if(text_to_draw[count]==' ') last_non_printing_character= count; count++; } if(count!=strlen(text_to_draw)) { char remaining_text_to_draw[256]; screen_rectangle new_destination; /* If we ever have to wrap text, we can't also center vertically. Sorry */ flags &= ~_center_vertical; flags |= _top_justified; /* Pass the rest of it back in, recursively, on the next line.. */ BlockMove(&text_to_draw[last_non_printing_character+1], remaining_text_to_draw, strlen(&text_to_draw[last_non_printing_character+1])+1); new_destination= *destination; new_destination.top+= interface_fonts.line_spacing[font_id]; _draw_screen_text(remaining_text_to_draw, &new_destination, flags, font_id, text_color); /* now truncate our text to draw...*/ text_to_draw[last_non_printing_character]= 0; } } /* Handle the horizontal stuff. */ if(flags & _center_horizontal || flags & _right_justified) { short text_width; text_width= TextWidth(text_to_draw, 0, strlen(text_to_draw)); if(text_width>RECTANGLE_WIDTH(destination)) { short length; short trunc_code; /* Truncate the puppy.. */ x= destination->left; length= strlen(text); trunc_code= TruncText(RECTANGLE_WIDTH(destination), text_to_draw, &length, truncEnd); text_to_draw[length]= 0; /* Now recenter it.. */ text_width= TextWidth(text_to_draw, 0, strlen(text_to_draw)); if (flags & _center_horizontal) x= destination->left+(((destination->right-destination->left)-text_width)>>1); else
void _draw_screen_text(const char *text, screen_rectangle *destination, short flags, short font_id, short text_color) { int x, y; // Find font information assert(font_id >= 0 && font_id < NUMBER_OF_INTERFACE_FONTS); uint16 style = InterfaceFonts[font_id].Style; const font_info *font = InterfaceFonts[font_id].Info; if (font == NULL) return; // Get color SDL_Color color; _get_interface_color(text_color, &color); // Copy the text to draw char text_to_draw[256]; strncpy(text_to_draw, text, 256); text_to_draw[255] = 0; // Check for wrapping, and if it occurs, be recursive if (flags & _wrap_text) { int last_non_printing_character = 0, text_width = 0; unsigned count = 0; while (count < strlen(text_to_draw) && text_width < RECTANGLE_WIDTH(destination)) { text_width += char_width(text_to_draw[count], font, style); if (text_to_draw[count] == ' ') last_non_printing_character = count; count++; } if( count != strlen(text_to_draw)) { char remaining_text_to_draw[256]; screen_rectangle new_destination; // If we ever have to wrap text, we can't also center vertically. Sorry. flags &= ~_center_vertical; flags |= _top_justified; // Pass the rest of it back in, recursively, on the next line memcpy(remaining_text_to_draw, text_to_draw + last_non_printing_character + 1, strlen(text_to_draw + last_non_printing_character + 1) + 1); new_destination = *destination; new_destination.top += InterfaceFonts[font_id].LineSpacing; _draw_screen_text(remaining_text_to_draw, &new_destination, flags, font_id, text_color); // Now truncate our text to draw text_to_draw[last_non_printing_character] = 0; } } // Truncate text if necessary int t_width = text_width(text_to_draw, font, style); if (t_width > RECTANGLE_WIDTH(destination)) { text_to_draw[trunc_text(text_to_draw, RECTANGLE_WIDTH(destination), font, style)] = 0; t_width = text_width(text_to_draw, font, style); } // Horizontal positioning if (flags & _center_horizontal) x = destination->left + (((destination->right - destination->left) - t_width) / 2); else if (flags & _right_justified) x = destination->right - t_width; else x = destination->left; // Vertical positioning int t_height = InterfaceFonts[font_id].Height; if (flags & _center_vertical) { if (t_height > RECTANGLE_HEIGHT(destination)) y = destination->top; else { y = destination->bottom; int offset = RECTANGLE_HEIGHT(destination) - t_height; y -= (offset / 2) + (offset & 1) + 1; } } else if (flags & _top_justified) { if (t_height > RECTANGLE_HEIGHT(destination)) y = destination->bottom; else y = destination->top + t_height; } else y = destination->bottom; // Now draw it draw_text(text_to_draw, x, y, SDL_MapRGB(draw_surface->format, color.r, color.g, color.b), font, style); }