Exemplo n.º 1
0
LRESULT CALLBACK ChessView::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{int cvtp=1;int figura;RECT rc2;BOOL postv;BOOL postvput;
rc2.left=rc2.top=0;
rc2.bottom=rc2.right=8*RAZMER+2;
	PAINTSTRUCT ps;
   HDC hdc;
HDC  hdc2;
int xf,yf;//для постановки-куда предпологаем ставить
int z;int z2;

ChessView *p=(ChessView *) GetWindowLong(hWnd, GWL_USERDATA);
	switch (message)
	{case WM_CLOSE:
		case WM_DESTROY:
			
			DeleteObject(hBmp1);//Удалим
			DeleteDC(hMemDC1);
		
	case WM_CREATE:

		p=(ChessView *) (((CREATESTRUCT *)lParam)->lpCreateParams);
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) p );
		
		break;
	case WM_PAINT:
		
		// тута рисовать
		cvtp=1;
		hdc=GetDC(hWnd);//Получим HDC
		//hdc = BeginPaint(hWnd, &ps);
		hMemDC1=CreateCompatibleDC(hdc);
		hBmp1=CreateCompatibleBitmap(hdc,rc2.bottom,rc2.bottom);
		SelectObject(hMemDC1,hBmp1);
		
		for(int x=1;x<=8;x++){
			for(int y=1;y<=8;y++){
		
			if(cvtp==1){ TransparentImage(hMemDC1,(x-1)*RAZMER,(y-1)*RAZMER,RAZMER,RAZMER, bmpc, 13*RAZMERSKIN, 0, RAZMERSKIN, RAZMERSKIN, transparentColorCH);}else{TransparentImage(hMemDC1,(x-1)*RAZMER,(y-1)*RAZMER,RAZMER,RAZMER, bmpc, 14*RAZMERSKIN, 0, RAZMERSKIN, RAZMERSKIN, transparentColorCH);}
			if(cvtp==2){cvtp=1;}else{cvtp=2;}//рисуем квадрат
			//рисуем фигуру
			if(p->Chesspole[y][x]>6){figura=p->Chesspole[y][x]-4;}else{figura=p->Chesspole[y][x];}
						 TransparentImage(hMemDC1,(x-1)*RAZMER,(y-1)*RAZMER,RAZMER,RAZMER, bmpc, figura*RAZMERSKIN, 0, RAZMERSKIN, RAZMERSKIN, transparentColorCH);
			if(p->flagaktiv==1 && p->fokus_x==x && p->fokus_y==y){TransparentImage(hMemDC1,(x-1)*RAZMER,(y-1)*RAZMER,RAZMER,RAZMER, bmpc, 15*RAZMERSKIN, 0, RAZMERSKIN, RAZMERSKIN, transparentColorCH);}
			
			}
			if(cvtp==2){cvtp=1;}else{cvtp=2;}
		}
	
		hdc2 = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		
		BitBlt(hdc,0,0,rc2.bottom,rc2.bottom,hMemDC1,0,0,SRCCOPY);//Скопируем рисунок из памяти
	//	EndPaint(hWnd, &ps);
		
		break;

	case  IDC_WM_VYBOR:{
        
				
					p->fokus_x=(p->pt2.x)/RAZMER+1;
					p->fokus_y=(p->pt2.y)/RAZMER+1;
				p->fokus_f=p->Chesspole[p->fokus_y][p->fokus_x];
				p->flagaktiv=1;//нажали
				if(p->fokus_f==0)p->flagaktiv=0;
				InvalidateRect(hWnd,&rc2,1);
				PostMessage (hWnd, WM_PAINT, 0, 0);

					  // UpdateWindow(hWnd);
					   }
			
			
					   break;

	case IDC_WM_STAV:
		xf=(p->pt2.x)/RAZMER+1;
		yf=(p->pt2.y)/RAZMER+1;
				postvput=0;
				postv=0;
				if(p->fokus_f<7 && (p->Chesspole[yf][xf]>=7 || p->Chesspole[yf][xf]==0))postv=1;//на чужие или пусто
				if(p->fokus_f>6 && (p->Chesspole[yf][xf]<=6))postv=1;
               
				if(postv){//тут обрабатываем правильность хода в зависимости от фигуры
					if(p->fokus_f==1){postvput=0;//пешка
						if(p->fokus_y==7){//перепрыгнем на 2 вначале
							if(yf==5 && p->fokus_x==xf && p->Chesspole[6][xf]==0 && p->Chesspole[5][xf]==0){postvput=1;}else if(yf==6 && p->fokus_x==xf && p->Chesspole[6][xf]==0){postvput=1;}//
						
						}else{//на 1вперёд
						
							if(yf==p->fokus_y-1  && p->fokus_x==xf && p->Chesspole[yf][xf]==0){postvput=1;}//вперед на фигуру не идём
							if(yf==p->fokus_y-1  && (p->fokus_x==xf-1 || p->fokus_x==xf+1) && p->Chesspole[yf][xf]>6)postvput=1;//бьём на искось

						}


					//пешка-end
					}else if(p->fokus_f==11){postvput=0;//чёрнпешка
						
						if(p->fokus_y==2){//перепрыгнем на 2 вначале
							if(yf==4 && p->fokus_x==xf && p->Chesspole[3][xf]==0 && p->Chesspole[4][xf]==0){postvput=1;}else if(yf==3 && p->fokus_x==xf){postvput=1;}//
						
						}else{//на 1вперёд
						
							if(yf==p->fokus_y+1  && p->fokus_x==xf && p->Chesspole[yf][xf]==0){postvput=1;}//вперед на фигуру не идём
							if(yf==p->fokus_y+1  && (p->fokus_x==xf-1 || p->fokus_x==xf+1) && p->Chesspole[yf][xf]<7)postvput=1;//бьём на искось

							}

					//чёрнпешка-end
					}else if(p->fokus_f==2 || p->fokus_f==12){//тура
						if(yf==p->fokus_y){postvput=1;//горизонталь
						if(xf>p->fokus_x){//вправо
							for(z=p->fokus_x+1;z<xf;z++){if(p->Chesspole[yf][z]!=0)postvput=0;}}else if(xf<p->fokus_x){//ВЛЕВО
							for(z=p->fokus_x-1;z>xf;z--){if(p->Chesspole[yf][z]!=0)postvput=0;}}

						

						}else if(xf==p->fokus_x){postvput=1;//ВЕРТИКАЛЬ
						if(yf>p->fokus_y){//ВВЕРХ
							for(z=p->fokus_y+1;z<yf;z++){if(p->Chesspole[z][xf]!=0)postvput=0;}}else if(yf<p->fokus_y){//ВНИЗ
							for(z=p->fokus_y-1;z>yf;z--){if(p->Chesspole[z][xf]!=0)postvput=0;}}

						

						}


//тура-end
					}else if(p->fokus_f==3 || p->fokus_f==13){//конь

						if(xf==p->fokus_x-2 && yf==p->fokus_y-1)postvput=1;
						if(xf==p->fokus_x-1 && yf==p->fokus_y-2)postvput=1;
						if(xf==p->fokus_x+1 && yf==p->fokus_y-2)postvput=1;
						if(xf==p->fokus_x+2 && yf==p->fokus_y-1)postvput=1;
						if(xf==p->fokus_x+2 && yf==p->fokus_y+1)postvput=1;
						if(xf==p->fokus_x+1 && yf==p->fokus_y+2)postvput=1;
						if(xf==p->fokus_x-1 && yf==p->fokus_y+2)postvput=1;
						if(xf==p->fokus_x-2 && yf==p->fokus_y+1)postvput=1;

				
//конь-конец
					}else if(p->fokus_f==4 || p->fokus_f==14){//слон

						if(abs(p->fokus_x-xf)==abs(p->fokus_y-yf)){postvput=1;
						z2=0;
						if(p->fokus_x<xf){//право
							for(z=p->fokus_x+1;z<xf;z++){
								if(p->fokus_y<yf && p->Chesspole[p->fokus_y+1+z2][z]!=0){postvput=0;}
								else 
									if(p->fokus_y>yf && p->Chesspole[p->fokus_y-1-z2][z]!=0){postvput=0;}
							++z2;
							}
						}else 
							if(p->fokus_x>xf){
							for(z=p->fokus_x-1;z>xf;z--){
								if(p->fokus_y<yf && p->Chesspole[p->fokus_y+1+z2][z]!=0){postvput=0;}
								else 
									if(p->fokus_y>yf && p->Chesspole[p->fokus_y-1-z2][z]!=0){postvput=0;}
							++z2;
						}
						
							}}
						
						

//слон-конец
					}else if(p->fokus_f==5 || p->fokus_f==15){//ферзь

//как слон 
					if(abs(p->fokus_x-xf)==abs(p->fokus_y-yf)){postvput=1;
						z2=0;
						if(p->fokus_x<xf){//право
							for(z=p->fokus_x+1;z<xf;z++){
								if(p->fokus_y<yf && p->Chesspole[p->fokus_y+1+z2][z]!=0){postvput=0;}
								else 
									if(p->fokus_y>yf && p->Chesspole[p->fokus_y-1-z2][z]!=0){postvput=0;}
							++z2;
							}
						}else 
							if(p->fokus_x>xf){
							for(z=p->fokus_x-1;z>xf;z--){
								if(p->fokus_y<yf && p->Chesspole[p->fokus_y+1+z2][z]!=0){postvput=0;}
								else 
									if(p->fokus_y>yf && p->Chesspole[p->fokus_y-1-z2][z]!=0){postvput=0;}
							++z2;
						}
						
							}}else{
//или тура
						if(yf==p->fokus_y){postvput=1;//горизонталь
						if(xf>p->fokus_x){//вправо
							for(z=p->fokus_x+1;z<xf;z++){if(p->Chesspole[yf][z]!=0)postvput=0;}}else if(xf<p->fokus_x){//ВЛЕВО
							for(z=p->fokus_x-1;z>xf;z--){if(p->Chesspole[yf][z]!=0)postvput=0;}}

						

						}else if(xf==p->fokus_x){postvput=1;//ВЕРТИКАЛЬ
						if(yf>p->fokus_y){//ВВЕРХ
							for(z=p->fokus_y+1;z<yf;z++){if(p->Chesspole[z][xf]!=0)postvput=0;}}else if(yf<p->fokus_y){//ВНИЗ
							for(z=p->fokus_y-1;z>yf;z--){if(p->Chesspole[z][xf]!=0)postvput=0;}}

						

						}}


//конец ферз
					}else if(p->fokus_f==6 || p->fokus_f==16){postvput=0;//король

						if(abs(yf-p->fokus_y)==1  || abs(p->fokus_x-xf)==1){postvput=1;
						if(p->fokus_f==6)p->rocb=4;
						if(p->fokus_f==16)p->rokch=4;
						
						
						}//тут будет рокоровка else if()

//конец король
					}

				}
			
				//поставили
				if( postvput){
				p->Chesspole[p->fokus_y][p->fokus_x]=0;
				p->fokus_x=(p->pt2.x)/RAZMER+1;
				p->fokus_y=(p->pt2.y)/RAZMER+1;
				
				p->Chesspole[p->fokus_y][p->fokus_x]=p->fokus_f;

				}
				//UpdateWindow(hWnd);//
				InvalidateRect(hWnd,&rc2,1);
				PostMessage (hWnd, WM_PAINT,0 , 0);
					p->flagaktiv=0;
					 
					 break;

		case WM_LBUTTONDOWN:
			
		

			SetFocus(hWnd);
            SHRGINFO    shrg;
            shrg.cbSize = sizeof(shrg);
            shrg.hwndClient = hWnd;
            shrg.ptDown.x = LOWORD(lParam);
            shrg.ptDown.y = HIWORD(lParam);
            shrg.dwFlags = SHRG_RETURNCMD /*| SHRG_NOANIMATION*/;

			if (SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {

              
 
                HMENU hmenu = CreatePopupMenu();
                if (hmenu==NULL) break;

				
                
                if(p->flagaktiv==0)AppendMenu(hmenu, MF_STRING, WM_VYBOR, TEXT("Выбрать") );
				if(p->flagaktiv==1){AppendMenu(hmenu, MF_STRING, WM_STAV, TEXT("Поставить") );
				AppendMenu(hmenu, MF_STRING, WM_OTMENA_VYBOR, TEXT("Отмена выбора") );}
                AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
                AppendMenu(hmenu, MF_STRING, EM_UNDO, TEXT("Отмена") );
				AppendMenu(hmenu, MF_STRING, SB_, TEXT("Пригласить") );
				AppendMenu(hmenu, MF_STRING, SB_, TEXT("Сдаться") );
				AppendMenu(hmenu, MF_STRING, SB_, TEXT("Ничья") );
POINT pt;		 p->pt2.x=GET_X_LPARAM(lParam);
				p->pt2.y=GET_Y_LPARAM(lParam);
               pt.x=GET_X_LPARAM(lParam);
				pt.y=GET_Y_LPARAM(lParam);
                ClientToScreen(hWnd, &pt);

                int cmdId=TrackPopupMenuEx(hmenu,
                    TPM_BOTTOMALIGN | TPM_RETURNCMD,
                    pt.x, pt.y,
                    hWnd,
                    NULL);
                if (cmdId==WM_VYBOR)PostMessage(hWnd, IDC_WM_VYBOR,0 , 0);
                if (cmdId==WM_STAV)PostMessage(hWnd, IDC_WM_STAV,0 , 0);

                return 0;
			}

		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
Exemplo n.º 2
0
// TODO code: optimise airspace drawing (same as DrawAirSpace())
// draw airspace using alpha blending
//static 
void MapWindow::DrawTptAirSpace(HDC hdc, const RECT rc) {
  // since standard GDI functions (brushes, pens...) ignore alpha octet in ARGB 
  // color value and don't set it in the resulting bitmap, we cannot use
  // perpixel alpha blending, instead we use global opacity for alpha blend 
  // (same opacity for all pixels); for fully "transparent" areas (without 
  // airspace) we must copy destination bitmap into source bitmap first so that 
  // alpha blending of such areas results in the same pixels as origin pixels 
  // in destination 
  CAirspaceList::const_iterator it;
  CAirspaceList::const_reverse_iterator itr;
  const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetNearAirspacesRef();
  int airspace_type;
  bool found = false;
  bool borders_only = (GetAirSpaceFillType() == asp_fill_ablend_borders);
  HDC hdcbuffer = NULL;
  HBITMAP hbbufferold = NULL, hbbuffer = NULL;
  static bool asp_selected_flash = false;
  asp_selected_flash = !asp_selected_flash;
  
  if (borders_only) {
    // Prepare layers
    hdcbuffer = CreateCompatibleDC(hdc);
    hbbuffer = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);
    hbbufferold = (HBITMAP)SelectObject(hdcbuffer, hbbuffer);
    BitBlt(hdcbuffer, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, rc.left, rc.top, BLACKNESS );
    SelectObject(hdcbuffer, GetStockObject(NULL_PEN));
  
    BitBlt(hDCMask, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, NULL, rc.left, rc.top, BLACKNESS );
    SelectObject(hDCMask, hAirspaceBorderPen);
    SelectObject(hDCMask, GetStockObject(HOLLOW_BRUSH));
  }

  // Draw airspace area
    if (1) {
    CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef());
    if (borders_only) {
       // Draw in reverse order!
       // The idea behind this, is lower top level airspaces are smaller. (statistically)
       // They have to be draw later, because inside border area have to be in correct color,
       // not the color of the bigger airspace above this small one.
      for (itr=airspaces_to_draw.rbegin(); itr != airspaces_to_draw.rend(); ++itr) {
            if ((*itr)->DrawStyle() == adsFilled) {
              airspace_type = (*itr)->Type();
              if (!found) {
                found = true;
                ClearTptAirSpace(hdc, rc);
              }
              // set filling brush
              SelectObject(hdcbuffer, GetAirSpaceSldBrushByClass(airspace_type));
              (*itr)->Draw(hdcbuffer, rc, true);
              (*itr)->Draw(hDCMask, rc, false);
            }
      }//for
    } else {
       // Draw in direct order!
      for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) {
            if ((*it)->DrawStyle() == adsFilled) {
              airspace_type = (*it)->Type();
              if (!found) {
                found = true;
                ClearTptAirSpace(hdc, rc);
              }
              // set filling brush
              SelectObject(hDCTemp, GetAirSpaceSldBrushByClass(airspace_type));
              (*it)->Draw(hDCTemp, rc, true);
            }
      }//for
    }//else borders_only
    }//mutex release

  // alpha blending
  if (found) {
    if (borders_only) {
      #if (WINDOWSPC<1)
        TransparentImage(hdcbuffer,
                rc.left,rc.top,
                rc.right-rc.left,rc.bottom-rc.top,
                hDCMask,
                rc.left,rc.top,
                rc.right-rc.left,rc.bottom-rc.top,
                RGB_WHITE
                );
        TransparentImage(hDCTemp,
                rc.left,rc.top,
                rc.right-rc.left,rc.bottom-rc.top,
                hdcbuffer,
                rc.left,rc.top,
                rc.right-rc.left,rc.bottom-rc.top,
                RGB_BLACK
                );
        #else
        TransparentBlt(hdcbuffer,
                      rc.left,rc.top,
                      rc.right-rc.left,rc.bottom-rc.top,
                      hDCMask,
                      rc.left,rc.top,
                      rc.right-rc.left,rc.bottom-rc.top,
                      RGB_WHITE
                      );
        TransparentBlt(hDCTemp,
                      rc.left,rc.top,
                      rc.right-rc.left,rc.bottom-rc.top,
                      hdcbuffer,
                      rc.left,rc.top,
                      rc.right-rc.left,rc.bottom-rc.top,
                      RGB_BLACK
                      );
        #endif
    }
    DoAlphaBlend(hdc, rc, hDCTemp, rc, (255 * GetAirSpaceOpacity()) / 100);
  }
  
  // draw it again, just the outlines
  
  // we will be drawing directly into given hdc, so store original PEN object
  HPEN hOrigPen = (HPEN) SelectObject(hdc, GetStockObject(WHITE_PEN));

    if (1) {
    CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef());
	for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) {
        if ((*it)->DrawStyle()) {
		  airspace_type = (*it)->Type();
		  if (bAirspaceBlackOutline ^ (asp_selected_flash && (*it)->Selected()) ) {
			SelectObject(hdc, GetStockObject(BLACK_PEN));
		  } else {
			SelectObject(hdc, hAirspacePens[airspace_type]);
		  }
		  (*it)->Draw(hdc, rc, false);
        }
	}//for
    }

  if (borders_only) {
    // Free up GDI resources
    SelectObject(hdcbuffer, hbbufferold);
    DeleteObject(hbbuffer);
    DeleteDC(hdcbuffer);
  }
  
  // restore original PEN
  SelectObject(hdc, hOrigPen);
} // DrawTptAirSpace()
Exemplo n.º 3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e H T M L I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method WriteHTMLImage writes an image in the HTML encoded image format.
%
%  The format of the WriteHTMLImage method is:
%
%      unsigned int WriteHTMLImage(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o status: Method WriteHTMLImage return True if the image is written.
%      False is returned is there is a memory shortage or if the image file
%      fails to write.
%
%    o image_info: Specifies a pointer to an ImageInfo structure.
%
%    o image:  A pointer to a Image structure.
%
%
*/
Export unsigned int WriteHTMLImage(const ImageInfo *image_info,Image *image)
{
  char
    buffer[MaxTextExtent],
    filename[MaxTextExtent],
    mapname[MaxTextExtent],
    url[MaxTextExtent];

  Image
    *next;

  ImageInfo
    *local_info;

  int
    x,
    y;

  register char
    *p;

  register PixelPacket
    *q;

  unsigned int
    height,
    status,
    width;

  /*
    Open image.
  */
  status=OpenBlob(image_info,image,WriteBinaryType);
  if (status == False)
    WriterExit(FileOpenWarning,"Unable to open file",image);
  CloseBlob(image);
  TransformRGBImage(image,RGBColorspace);
  *url='\0';
  if ((Latin1Compare(image_info->magick,"FTP") == 0) ||
      (Latin1Compare(image_info->magick,"HTTP") == 0))
    {
      /*
        Extract URL base from filename.
      */
      p=strrchr(image->filename,'/');
      if (p)
        {
          p++;
          (void) strcpy(url,image_info->magick);
          (void) strcat(url,":");
          url[Extent(url)+p-image->filename]='\0';
          (void) strncat(url,image->filename,p-image->filename);
          (void) strcpy(image->filename,p);
        }
    }
  /*
    Refer to image map file.
  */
  (void) strcpy(filename,image->filename);
  AppendImageFormat("map",filename);
  (void) strcpy(mapname,BaseFilename(filename));
  (void) strcpy(image->filename,image_info->filename);
  (void) strcpy(filename,image->filename);
  local_info=CloneImageInfo(image_info);
  if (local_info == (ImageInfo *) NULL)
    WriterExit(FileOpenWarning,"Unable to allocate memory",image);
  local_info->adjoin=True;
  status=True;
  if (Latin1Compare(image_info->magick,"SHTML") != 0)
    {
      /*
        Open output image file.
      */
      status=OpenBlob(image_info,image,WriteBinaryType);
      if (status == False)
        WriterExit(FileOpenWarning,"Unable to open file",image);
      /*
        Write the HTML image file.
      */
      (void) strcpy(buffer,"<html version=\"2.0\">\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"<head>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) sprintf(buffer,"<title>%.1024s</title>\n",
        image->label ? image->label : BaseFilename(image->filename));
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"</head>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"<body>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"<center>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) sprintf(buffer,"<h1>%.1024s</h1>\n",image->filename);
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"<br><br>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(filename,image->filename);
      AppendImageFormat("gif",filename);
      (void) sprintf(buffer,
        "<img ismap usemap=#%.1024s src=\"%.1024s\" border=0>\n",
        mapname,filename);
      (void) WriteBlob(image,strlen(buffer),buffer);
      /*
        Determine the size and location of each image tile.
      */
      width=image->columns;
      height=image->rows;
      x=0;
      y=0;
      if (image->montage != (char *) NULL)
        (void) ParseGeometry(image->montage,&x,&y,&width,&height);
      /*
        Write an image map.
      */
      (void) sprintf(buffer,"<map name=%.1024s>\n",mapname);
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) sprintf(buffer,"  <area href=""%.1024s""",url);
      (void) WriteBlob(image,strlen(buffer),buffer);
      if (image->directory == (char *) NULL)
        {
          (void) sprintf(buffer,"%.1024s shape=rect coords=0,0,%u,%u>\n",
            image->filename,width-1,height-1);
          (void) WriteBlob(image,strlen(buffer),buffer);
        }
      else
        for (p=image->directory; *p != '\0'; p++)
          if (*p != '\n')
            (void) WriteByte(image,*p);
          else
            {
              (void) sprintf(buffer," shape=rect coords=%d,%d,%d,%d>\n",
                x,y,x+(int) width-1,y+(int) height-1);
              (void) WriteBlob(image,strlen(buffer),buffer);
              if (*(p+1) != '\0')
                {
                  (void) sprintf(buffer,"  <area href=""%.1024s""",url);
                  (void) WriteBlob(image,strlen(buffer),buffer);
                }
              x+=width;
              if (x >= (int) image->columns)
                {
                  x=0;
                  y+=height;
                }
            }
      (void) strcpy(buffer,"</map>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      if (image->montage != (char *) NULL)
        {
          char
            color[MaxTextExtent] = "#000";

          /*
            Make montage background transparent.
          */
          q=GetPixelCache(image,0,0,1,1);
          if (q != (PixelPacket *) NULL)
            FormatString(color,HexColorFormat,q->red,q->green,q->blue);
          TransparentImage(image,color);
        }
      (void) strcpy(filename,image->filename);
      (void) strcpy(buffer,"</center>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"</body>\n");
      (void) WriteBlob(image,strlen(buffer),buffer);
      (void) strcpy(buffer,"</html>\n");
      status=WriteBlob(image,strlen(buffer),buffer);
      CloseBlob(image);
      /*
        Write the image as transparent GIF.
      */
      (void) strcpy(image->filename,filename);
      AppendImageFormat("gif",image->filename);
      next=image->next;
      image->next=(Image *) NULL;
      status|=WriteGIFImage(local_info,image);
      image->next=next;
      /*
        Determine image map filename.
      */
      (void) strcpy(image->filename,filename);
      for (p=filename+Extent(filename)-1; p > (filename+1); p--)
        if (*p == '.')
          {
            (void) strncpy(image->filename,filename,p-filename);
            image->filename[p-filename]='\0';
            break;
          }
      (void) strcat(image->filename,"_map.shtml");
    }
  /*
    Open image map.
  */
  status=OpenBlob(local_info,image,WriteBinaryType);
  if (status == False)
    WriterExit(FileOpenWarning,"Unable to open file",image);
  DestroyImageInfo(local_info);
  /*
    Determine the size and location of each image tile.
  */
  width=image->columns;
  height=image->rows;
  x=0;
  y=0;
  if (image->montage != (char *) NULL)
    (void) ParseGeometry(image->montage,&x,&y,&width,&height);
  /*
    Write an image map.
  */
  (void) sprintf(buffer,"<map name=%.1024s>\n",mapname);
  (void) WriteBlob(image,strlen(buffer),buffer);
  (void) sprintf(buffer,"  <area href=""%.1024s""",url);
  (void) WriteBlob(image,strlen(buffer),buffer);
  if (image->directory == (char *) NULL)
    {
      (void) sprintf(buffer,"%.1024s shape=rect coords=0,0,%u,%u>\n",
        image->filename,width-1,height-1);
      (void) WriteBlob(image,strlen(buffer),buffer);
    }
  else
    for (p=image->directory; *p != '\0'; p++)
      if (*p != '\n')
        (void) WriteByte(image,*p);
      else
        {
          (void) sprintf(buffer," shape=rect coords=%d,%d,%d,%d>\n",x,y,
            x+(int) width-1,y+(int) height-1);
          (void) WriteBlob(image,strlen(buffer),buffer);
          if (*(p+1) != '\0')
            {
              (void) sprintf(buffer,"  <area href=""%.1024s""",url);
              (void) WriteBlob(image,strlen(buffer),buffer);
            }
          x+=width;
          if (x >= (int) image->columns)
            {
              x=0;
              y+=height;
            }
        }
  (void) strcpy(buffer,"</map>\n");
  (void) WriteBlob(image,strlen(buffer),buffer);
  CloseBlob(image);
  (void) strcpy(image->filename,filename);
  return(status);
}