///ImageBackFill_CopyScaledBitMap() static void ImageBackFill_CopyScaledBitMap ( struct RastPort *SrcRast, WORD SrcOffsetX, WORD SrcOffsetY, WORD SrcSizeX, WORD SrcSizeY, struct RastPort *DstRast, struct Rectangle *DstAreaBounds, struct Rectangle *DstFillBounds, ULONG blit_MODE ) { struct BitScaleArgs Scale_Args; D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyScaledBitMap()\n")); Scale_Args.bsa_SrcX = SrcOffsetX; Scale_Args.bsa_SrcY = SrcOffsetY; Scale_Args.bsa_SrcWidth = SrcSizeX; Scale_Args.bsa_SrcHeight = SrcSizeY; Scale_Args.bsa_XSrcFactor = SrcSizeX; Scale_Args.bsa_YSrcFactor = SrcSizeY; Scale_Args.bsa_DestX = DstFillBounds->MinX; Scale_Args.bsa_DestY = DstFillBounds->MinY; Scale_Args.bsa_XDestFactor = (DstFillBounds->MaxX - DstFillBounds->MinX) + 1; Scale_Args.bsa_YDestFactor = (DstFillBounds->MaxY - DstFillBounds->MinY) + 1; Scale_Args.bsa_SrcBitMap = SrcRast->BitMap; Scale_Args.bsa_DestBitMap = DstRast->BitMap; BitMapScale(&Scale_Args); }
static void scaleBitMap(struct data *data,UWORD w,UWORD h) { register UWORD x, y; if (w==data->picWidth && h==data->picHeight) return; if (w==0 || w>16383 || h==0 || h>16383) return; x = ScalerDiv(w,FACTOR,data->picWidth); y = ScalerDiv(h,FACTOR,data->picHeight); if (x==0 || x>16383 || y==0 || y>16383) return; w = ScalerDiv(x,data->picWidth,FACTOR); h = ScalerDiv(y,data->picHeight,FACTOR); if (w==0 || w>16383 || h==0 || h>16383) return; if (data->scaledBitMap = AllocBitMap(w,h,data->bmh->bmh_Depth,((data->flags & FLG_Cyber) ? BMF_MINPLANES : 0)|BMF_CLEAR,data->screen->RastPort.BitMap)) { struct BitScaleArgs scale; memset(&scale,0,sizeof(struct BitScaleArgs)); scale.bsa_SrcBitMap = data->bitMap; scale.bsa_DestBitMap = data->scaledBitMap; scale.bsa_SrcWidth = data->picWidth; scale.bsa_SrcHeight = data->picHeight; scale.bsa_XSrcFactor = FACTOR; scale.bsa_XDestFactor = x; scale.bsa_YSrcFactor = FACTOR; scale.bsa_YDestFactor = y; BitMapScale(&scale); data->scaledWidth = w; data->scaledHeight = h; scaleMask(data,data->picWidth,data->picHeight,scale.bsa_DestWidth,scale.bsa_DestHeight,x,y); SetSuperAttrs(data->cl,data->obj,MUIA_Pic_Width,w,MUIA_Pic_Height,h,TAG_DONE); } }
static void scaleMask(struct data *data,UWORD bpr,UWORD rows,UWORD dw,UWORD dh,UWORD xdf,UWORD ydf) { if (data->scaledBitMap && data->plane) { struct BitMap *bm; if (bm = AllocBitMap(dw,dh,1,0,NULL)) { struct BitScaleArgs bsa; struct BitMap sbm; memset(&sbm,0,sizeof(sbm)); sbm.BytesPerRow = RAWIDTH(bpr); sbm.Rows = rows; sbm.Depth = 1; sbm.Planes[0] = data->plane; memset(&bsa,0,sizeof(bsa)); bsa.bsa_SrcBitMap = &sbm; bsa.bsa_DestBitMap = bm; bsa.bsa_SrcWidth = data->picWidth; bsa.bsa_SrcHeight = data->picHeight; bsa.bsa_XSrcFactor = FACTOR; bsa.bsa_XDestFactor = xdf; bsa.bsa_YSrcFactor = FACTOR; bsa.bsa_YDestFactor = ydf; BitMapScale(&bsa); data->planeBitMap = bm; } } }
bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap, const char *url) { struct BitScaleArgs bsa; int plot_width; int plot_height; int redraw_tile_size = nsoption_int(redraw_tile_size_x); struct redraw_context ctx = { .interactive = false, .background_images = true, .plot = &amiplot }; if(nsoption_int(redraw_tile_size_y) < nsoption_int(redraw_tile_size_x)) redraw_tile_size = nsoption_int(redraw_tile_size_y); plot_width = MIN(content_get_width(content), redraw_tile_size); plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) / bitmap->width; bitmap->nativebm = p96AllocBitMap(bitmap->width, bitmap->height, 32, BMF_CLEAR | BMF_DISPLAYABLE | BMF_INTERLEAVED, browserglob.bm, RGBFB_A8R8G8B8); bitmap->nativebmwidth = bitmap->width; bitmap->nativebmheight = bitmap->height; ami_clearclipreg(&browserglob); thumbnail_redraw(content, plot_width, plot_height, &ctx); if(GfxBase->LibNode.lib_Version >= 53) // AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) { float resample_scale = bitmap->width / (float)plot_width; uint32 flags = COMPFLAG_IgnoreDestAlpha | COMPFLAG_SrcAlphaOverride; if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter; CompositeTags(COMPOSITE_Src,browserglob.bm,bitmap->nativebm, COMPTAG_ScaleX, COMP_FLOAT_TO_FIX(resample_scale), COMPTAG_ScaleY, COMP_FLOAT_TO_FIX(resample_scale), COMPTAG_Flags,flags, COMPTAG_DestX,0, COMPTAG_DestY,0, COMPTAG_DestWidth,bitmap->width, COMPTAG_DestHeight,bitmap->height, COMPTAG_OffsetX,0, COMPTAG_OffsetY,0, TAG_DONE); } else { bsa.bsa_SrcX = 0; bsa.bsa_SrcY = 0; bsa.bsa_SrcWidth = plot_width; bsa.bsa_SrcHeight = plot_height; bsa.bsa_DestX = 0; bsa.bsa_DestY = 0; // bsa.bsa_DestWidth = width; // bsa.bsa_DestHeight = height; bsa.bsa_XSrcFactor = plot_width; bsa.bsa_XDestFactor = bitmap->width; bsa.bsa_YSrcFactor = plot_height; bsa.bsa_YDestFactor = bitmap->height; bsa.bsa_SrcBitMap = browserglob.bm; bsa.bsa_DestBitMap = bitmap->nativebm; bsa.bsa_Flags = 0; BitMapScale(&bsa); } if (url) urldb_set_thumbnail(url, bitmap); return true; }
// 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; }