// Update toolbar cache BOOL GetToolBarCache(ToolBarInfo *toolbar,BOOL real) { short depth,width,height,num,x,y; short last_width=0,last_height=0; Cfg_Button *button; struct TagItem tags[4]; struct Rectangle rect; // Invalid toolbar? if (!toolbar) return 0; // Free existing cache FreeToolBarCache(toolbar); // Remap toolbar if this is for real if (real && !toolbar->done_remap) { // Do remap RemapToolBar(toolbar); toolbar->done_remap=1; } // Initialise tags tags[0].ti_Tag=IM_Depth; tags[0].ti_Data=1; tags[1].ti_Tag=IM_Width; tags[1].ti_Data=0; tags[2].ti_Tag=IM_Height; tags[2].ti_Data=0; tags[3].ti_Tag=TAG_DONE; // Minimum depth depth=1; // Count items in toolbar for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,toolbar->count=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,toolbar->count++); // Allocate position array if (!(toolbar->button_array=AllocVec(sizeof(struct Rectangle)*(toolbar->count+2),MEMF_CLEAR))) { FreeToolBarCache(toolbar); return 0; } // Go through buttons again for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,num=0,toolbar->max_width=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,num++) { Cfg_ButtonFunction *func; short width,height,x; // Get left button image if ((func=(Cfg_ButtonFunction *) FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON)) && func->image) { // Get depth and other info GetImageAttrs(func->image,tags); // Biggest depth so far? if (tags[0].ti_Data>depth) depth=tags[0].ti_Data; // Get size width=tags[1].ti_Data; height=tags[2].ti_Data; } // Or textual button? else if (!(button->button.flags&BUTNF_GRAPHIC) && func) { struct TextExtent extent; // Get length of label TextExtent(&GUI->screen_pointer->RastPort,func->label,strlen(func->label),&extent); // Get size width=extent.te_Width; height=extent.te_Height; } // Use last size else { width=last_width; height=last_height; } // Minimum size if (width<2) width=8; if (height<2) height=8; // Save size last_width=width; last_height=height; // Increase size for border if (!(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) { width+=2; height+=2; } // Biggest width so far? if (width>toolbar->max_width) toolbar->max_width=width; // Get last position x=(num>0)?toolbar->button_array[num-1].MaxX+1:0; // Store position in array toolbar->button_array[num].MinX=x; toolbar->button_array[num].MinY=0; toolbar->button_array[num].MaxX=x+width-1; toolbar->button_array[num].MaxY=height-1; } // No actual buttons? if (toolbar->count<1 || depth<1) { FreeToolBarCache(toolbar); return 0; } // Store rows/cols toolbar->cols=toolbar->count; toolbar->rows=1; // Valid toolbar arrow? if (GUI->toolbar_arrow_image) { short width,height; // Get size of the arrow button GetImageAttrs(GUI->toolbar_arrow_image,tags); // Biggest depth so far? if (tags[0].ti_Data>depth) depth=tags[0].ti_Data; // Get size width=tags[1].ti_Data; height=tags[2].ti_Data; // Increase size for border if (!(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) { width+=2; height+=2; } // Store size in array toolbar->button_array[toolbar->count].MaxX=width-1; toolbar->button_array[toolbar->count].MaxY=height-1; // Add to maximum width toolbar->max_width+=width; } // Get height of toolbar for (num=0,height=0;num<=toolbar->count;num++) { if ((width=RECTHEIGHT(&toolbar->button_array[num]))>height) height=width; } // Store toolbar height toolbar->button_height=height; // Get cache size toolbar->width=toolbar->button_array[toolbar->count-1].MaxX+1; toolbar->height=toolbar->button_height; // Don't want cache? if (!real) return 1; // Allocate cache bitmap if (!(toolbar->bitmap= NewBitMap( toolbar->width, toolbar->height, depth, BMF_CLEAR, GUI->screen_pointer->RastPort.BitMap))) // 0))) { // Failed FreeToolBarCache(toolbar); return 0; } // Initialise RastPort InitRastPort(&toolbar->rp); toolbar->rp.BitMap=toolbar->bitmap; // Got cache successfully toolbar->cache=1; // Set pens and font SetAPen(&toolbar->rp,1); SetBPen(&toolbar->rp,0); SetFont(&toolbar->rp,GUI->screen_pointer->RastPort.Font); // Initialise draw tags tags[0].ti_Tag=IM_Rectangle; tags[0].ti_Data=(ULONG)▭ tags[1].ti_Tag=IM_ClipBoundary; tags[1].ti_Data=(toolbar->buttons->window.flags&BTNWF_BORDERLESS)?0:2; tags[2].ti_Tag=IM_NoIconRemap; tags[2].ti_Data=(environment->env->desktop_flags&DESKTOPF_NO_REMAP)?TRUE:FALSE; tags[3].ti_Tag=TAG_DONE; // Go through buttons for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,x=0,y=0,num=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,num++) { Cfg_ButtonFunction *func; BOOL ok=0; // Get button rectangle rect=toolbar->button_array[num]; // Get left button image if ((func=(Cfg_ButtonFunction *)FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON)) && func->image) { // Draw button image RenderImage(&toolbar->rp,func->image,0,0,tags); ok=1; } // Or textual button? else if (!(button->button.flags&BUTNF_GRAPHIC) && func && func->label && *func->label) { // Draw label Move(&toolbar->rp,x,y+toolbar->rp.TxBaseline); Text(&toolbar->rp,func->label,strlen(func->label)); ok=1; } // Draw button border if (!ok || !(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) DrawBox(&toolbar->rp,&rect,GUI->draw_info,0); } return 1; }
// Load a backfill pattern; pattern must be locked exclusively void GetPattern(PatternData *pattern,struct Screen *screen,ULONG border_col) { // Initially make invalid pattern->valid=FALSE; pattern->border_pen=0; // Set screen pointer pattern->screen=screen; // Check for invalid data if (!pattern->data) { // Update border pen GetPatternBorder(pattern,screen,border_col); return; } // Bitmap pattern? if (pattern->prefs.wbp_Flags&WBPF_PATTERN) { UWORD *ptr,*planes[MAXDEPTH]; short num,row,col,pen; // Get plane pointers for (num=0;num<pattern->prefs.wbp_Depth;num++) { planes[num]=((UWORD *)pattern->data)+(PAT_HEIGHT*num); } pattern->fill_plane_key=0; // Clear fill initially for (num=0,ptr=pattern->fill[0];num<128;num++,ptr++) *ptr=0; // Under 37 use fill pattern as supplied if (((struct Library *)GfxBase)->lib_Version<39) { for (num=0;num<pattern->prefs.wbp_Depth;num++) { CopyMem( (char *)planes[num], (char *)pattern->fill[num], PAT_HEIGHT*sizeof(UWORD)); } pattern->fill_plane_key=pattern->prefs.wbp_Depth; } // Otherwise, we need to remap else { // Go through pattern rows for (row=0;row<PAT_HEIGHT;row++) { // Go through bits for (col=0;col<PAT_WIDTH;col++) { // Clear pen pen=0; // Calculate pixel colour for (num=0;num<pattern->prefs.wbp_Depth;num++) { // Is bit set in this bitplane? if (planes[num][row]&(1<<col)) pen|=(1<<num); } // Pixel set? if (pen) { // Map pens 4-7 to top four colours if (pen>=4 && screen->RastPort.BitMap->Depth<=8) { pen=(1<<screen->RastPort.BitMap->Depth)-(8-pen); } // Remap for (num=0;num<8;num++) { // Want this bit? if (pen&(1<<num)) { // Set bit pattern->fill[num][row]|=1<<col; if (num>=pattern->fill_plane_key) pattern->fill_plane_key=num+1; } } } } } } // Any data? if (pattern->fill_plane_key>0) { short depth; // Get depth for bitmap if (((struct Library *)GfxBase)->lib_Version>=39) depth=GetBitMapAttr(screen->RastPort.BitMap,BMA_DEPTH); else depth=screen->RastPort.BitMap->Depth; // Check its not too deep if (depth>8) depth=8; // Allocate bitmap for pattern if ((pattern->pattern_bitmap= NewBitMap( PATTILE_SIZE, PATTILE_SIZE, depth, BMF_CLEAR, 0))) { struct RastPort rp; struct BitMap *bitmap; // Initialise dummy rastport InitRastPort(&rp); rp.BitMap=pattern->pattern_bitmap; // Set fill pattern SetAfPt(&rp,pattern->fill[0],-4); // Fill bitmap SetRast(&rp,0); RectFill(&rp,0,0,PATTILE_SIZE-1,PATTILE_SIZE-1); // Is the screen a non-standard bitmap? if (((struct Library *)GfxBase)->lib_Version>=39 && !(GetBitMapAttr(screen->RastPort.BitMap,BMA_FLAGS)&BMF_STANDARD)) { // Try and allocate friend bitmap if ((bitmap= NewBitMap( PATTILE_SIZE, PATTILE_SIZE, depth, BMF_CLEAR, screen->RastPort.BitMap))) { // Copy to friend bitmap BltBitMap( pattern->pattern_bitmap,0,0, bitmap,0,0, PATTILE_SIZE,PATTILE_SIZE, 0xc0,0xff,0); // Free original bitmap DisposeBitMap(pattern->pattern_bitmap); // Use new bitmap pointer pattern->pattern_bitmap=bitmap; } } // Get bitmap pointer pattern->bitmap=pattern->pattern_bitmap; // Get pattern size pattern->width=PATTILE_SIZE; pattern->height=PATTILE_SIZE; } } } // Picture; must have datatypes else if (DataTypesBase) { short len; BOOL remap=1; long precision=PRECISION_IMAGE; char name[256]; long ver=0; struct Library *pdt; #ifdef PATCH_OK APTR patchhandle=0; #endif // Check picture datatype version if ((pdt=OpenLibrary("sys:classes/datatypes/picture.datatype",0)) || (pdt=OpenLibrary("picture.datatype",0))) { // Get version ver=pdt->lib_Version; CloseLibrary(pdt); } // No remap? if ((len=strlen(pattern->data))>8 && stricmp(pattern->data+len-8,".noremap")==0) remap=0; // Precision? if (len>6 && stricmp(pattern->data+len-6,".exact")==0) precision=PRECISION_EXACT; // Specified in prefs? else if (pattern->precision) { if (pattern->precision==-1) remap=0; else if (pattern->precision==1) precision=PRECISION_ICON; else if (pattern->precision==2) precision=PRECISION_GUI; else if (pattern->precision==3) precision=PRECISION_EXACT; } #ifdef PATCH_OK // If we've got v43 of the datatype, we don't need the fastram patch if (ver<43) { // Add this task to the patchlist for allocbitmap patchhandle=AddAllocBitmapPatch(FindTask(0),screen); } #endif // Turn back on requesters ((struct Process *)FindTask(0))->pr_WindowPtr=GUI->window; // Check for random pictures, and then load picture if (pattern_check_random(pattern,name) && (pattern->object= NewDTObject(name, DTA_GroupID,GID_PICTURE, PDTA_Screen,screen, PDTA_FreeSourceBitMap,TRUE, (ver>42)?PDTA_DestMode:TAG_IGNORE,MODE_V43, (ver>42)?PDTA_UseFriendBitMap:TAG_IGNORE,TRUE, TAG_END))) { struct BitMapHeader *header; struct BitMap *bitmap; D_S(struct FileInfoBlock, fib) // Get file information if (GetFileInfo(name,fib) && strnicmp(fib->fib_Comment,"dopus ",6)==0) { char *args=fib->fib_Comment+6; short val; rexx_skip_space(&args); while ((val=rexx_match_keyword(&args,background_key,0))!=-1) { // Tile/center/stretch if (val==3) pattern->flags&=~(PATF_CENTER|PATF_STRETCH); else if (val==4) { pattern->flags|=PATF_CENTER; pattern->flags&=~PATF_STRETCH; } else if (val==5 && pattern->prefs.wbp_Which==0) { pattern->flags|=PATF_STRETCH; pattern->flags&=~PATF_CENTER; } // Precision else if (val==6) { // Get precision rexx_skip_space(&args); if ((val=rexx_match_keyword(&args,precision_key,0))>-1) { if (val==0) remap=0; else if (val==1) precision=PRECISION_GUI; else if (val==2) precision=PRECISION_ICON; else if (val==3) precision=PRECISION_IMAGE; else if (val==4) precision=PRECISION_EXACT; } } // Border else if (val==8) { // Off? rexx_skip_space(&args); if (rexx_match_keyword(&args,on_off_strings2,0)==0) border_col&=~ENVBF_USE_COLOUR; else { border_col=ENVBF_USE_COLOUR; border_col|=Atoh(args,-1)<<8; } } } } // Layout picture (should check for success) SetDTAttrs(pattern->object,0,0, OBP_Precision,precision, PDTA_Remap,remap, TAG_END); DoMethod(pattern->object,DTM_PROCLAYOUT,0,1); // Get bitmap pointer and header GetDTAttrs(pattern->object, PDTA_BitMap,&bitmap, PDTA_DestBitMap,&pattern->bitmap, PDTA_BitMapHeader,&header, TAG_END); // No dest bitmap? if (!pattern->bitmap) pattern->bitmap=bitmap; // Valid bitmap? if (pattern->bitmap) { // Get width and height pattern->width=header->bmh_Width; pattern->height=header->bmh_Height; } } // Turn off requesters ((struct Process *)FindTask(0))->pr_WindowPtr=(APTR)-1; #ifdef PATCH_OK // Remove this task from the patchlist for allocbitmap if (patchhandle) RemAllocBitmapPatch(patchhandle); #endif // Got bitmap? if (pattern->bitmap) { // Stretch? if (pattern->flags&PATF_STRETCH) { // Not the size of the screen? if (pattern->width!=screen->Width || pattern->height!=screen->Height) { // Allocate a bitmap for the stretched picture if ((pattern->pattern_bitmap= NewBitMap( screen->Width, screen->Height, GetBitMapAttr(pattern->bitmap,BMA_DEPTH), BMF_CLEAR, screen->RastPort.BitMap))) { struct BitScaleArgs scale; // Scale bitmap scale.bsa_SrcX=0; scale.bsa_SrcY=0; scale.bsa_SrcWidth=pattern->width; scale.bsa_SrcHeight=pattern->height; scale.bsa_DestX=0; scale.bsa_DestY=0; scale.bsa_DestWidth=screen->Width; scale.bsa_DestHeight=screen->Height; scale.bsa_XSrcFactor=scale.bsa_SrcWidth; scale.bsa_XDestFactor=scale.bsa_DestWidth; scale.bsa_YSrcFactor=scale.bsa_SrcHeight; scale.bsa_YDestFactor=scale.bsa_DestHeight; scale.bsa_SrcBitMap=pattern->bitmap; scale.bsa_DestBitMap=pattern->pattern_bitmap; scale.bsa_Flags=0; BitMapScale(&scale); // Get pointer to scaled bitmap pattern->bitmap=pattern->pattern_bitmap; pattern->width=screen->Width; pattern->height=screen->Height; } } } } // Update border pen GetPatternBorder(pattern,screen,border_col); } // Pattern ok now pattern->valid=TRUE; }