BOOL CDib::Read(CFile* pFile) //CFile ptr passed by the documents serialize function { // 1. read file header to get size of info hdr + color table // 2. read info hdr (to get image size) and color table // 3. read image Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; TRY { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { AfxMessageBox("Error reading header"); return FALSE; } if(bmfh.bfType != 0x4d42) { // 'BM' AfxMessageBox("Invalid bitmap file"); return FALSE; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table ComputeMetrics(); //sets m_dwSizeImage etc. m_lpImage = (LPBYTE) new char[m_dwSizeImage]; nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only } CATCH (CException, e) { AfxMessageBox("Error reading file (exception thrown)"); return FALSE; }
CDib::CDib(CSize size, int nBitCount) { m_hFile = NULL; m_hBitmap = NULL; m_hPalette = NULL; m_nBmihAlloc = m_nImageAlloc = noAlloc; Empty(); ComputePaletteSize(nBitCount); m_lpBMIH = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries]; m_nBmihAlloc = crtAlloc; m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER); m_lpBMIH->biWidth = size.cx; m_lpBMIH->biHeight = size.cy; m_lpBMIH->biPlanes = 1; m_lpBMIH->biBitCount = nBitCount; m_lpBMIH->biCompression = BI_RGB; m_lpBMIH->biSizeImage = 0; m_lpBMIH->biXPelsPerMeter = 0; m_lpBMIH->biYPelsPerMeter = 0; m_lpBMIH->biClrUsed = m_nColorTableEntries; m_lpBMIH->biClrImportant = m_nColorTableEntries; ComputeMetrics(); memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries); m_lpImage = NULL; // sin datos todavía }
BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal) { // asume que BITMAPINFOHEADER, la tabla de colores y la imagen son contiguos // la tabla de colores podría ser de longitud cero Empty(); m_hGlobal = hGlobal; if(bMustDelete == FALSE) { m_nBmihAlloc = noAlloc; } else { m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc); } try { m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem; ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntries; MakePalette(); } catch(CException* pe) { AfxMessageBox(_T("Error de AttachMemory")); pe->Delete(); return FALSE; } return TRUE; }
const gfxFont::Metrics& gfxDWriteFont::GetMetrics() { if (!mMetrics) { ComputeMetrics(); } return *mMetrics; }
/************************************************************************* * * \函数名称: * Read() * * \输入参数: * CFile* pFile - 指向CFile对象的指针 * * \返回值: * BOOL - 如果成功,则返回TRUE * * \说明: * 该函数DIB从一个文件读入CDib对象。该文件必须成功打开。如果该文件是BMP文件 * 读取工作从文件头开始。如果该文件是一个文档,读取工作则从当前文件指针处开始 * ************************************************************************ */ BOOL CDib::Read(CFile* pFile) { // 释放已经分配的内存 Empty(); // 临时存放信息的变量 int nCount, nSize; BITMAPFILEHEADER bmfh; // 进行读操作 try { // 读取文件头 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { throw new CException; } // 如果文件类型部位"BM",则返回并进行相应错误处理 if(bmfh.bfType != 0x4d42) { throw new CException; } // 计算信息头加上调色板的大小,并分配相应的内存 nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = m_nImageAlloc = crtAlloc; // 读取信息头和调色板 nCount = pFile->Read(m_lpBMIH, nSize); // 计算图象数据大小并设置调色板指针 ComputeMetrics(); // 计算调色板的表项数 ComputePaletteSize(m_lpBMIH->biBitCount); // 如果DIB中存在调色板,则创建一个Windows调色板 MakePalette(); // 分配图象数据内存,并从文件中读取图象数据 m_lpImage = (LPBYTE) new char[m_dwSizeImage]; nCount = pFile->Read(m_lpImage, m_dwSizeImage); } // 错误处理 catch(CException* pe) { AfxMessageBox("Read error"); pe->Delete(); return FALSE; } // 返回 return TRUE; }
BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */) { // nueva función que lee el BMP del disco y crea una sección de DIB // permite la modificación de mapas de bits de disco // 1. leer cabecera de archivo para obtener el tamaño de la cabecera de info + tabla de colores // 2. leer cabecera de info (para obtener el tamaño de la imagen) y la tabla de colores // 3. crear sección de DIB en función de los parámetros de la cabecera // 4. leer la imagen en memoria que asigna CreateDibSection Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; try { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { //throw new CException; throw new std::exception; } if(bmfh.bfType != 0x4d42) { //throw new CException; throw new std::exception; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = crtAlloc; m_nImageAlloc = noAlloc; nCount = pFile->Read(m_lpBMIH, nSize); // cabecera de info y tabla de colores if(m_lpBMIH->biCompression != BI_RGB) { //throw new CException; throw new std::exception; } ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); UsePalette(pDC); m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0); ASSERT(m_lpImage != NULL); nCount = pFile->Read(m_lpImage, m_dwSizeImage); // solo la imagen } catch(CException* pe) { AfxMessageBox(_T("Error de ReadSection")); pe->Delete(); return FALSE; } return TRUE; }
BOOL CDib::CopyToMapFile(const TCHAR* strPathname) { // copia el DIB en un nuevo archivo, libera los punteros antes // si se ha utilizado previamente CreateSection, el HBITMAP será NULL (y no utilizable) BITMAPFILEHEADER bmfh; bmfh.bfType = 0x4d42; // 'BM' bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER); // el significado de bfSize abierto a la interpretación bmfh.bfReserved1 = bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ASSERT(hFile != INVALID_HANDLE_VALUE); int nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries + m_dwSizeImage; HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NULL); DWORD dwErr = ::GetLastError(); ASSERT(hMap != NULL); LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // proyectar archivo completo ASSERT(lpvFile != NULL); LPBYTE lpbCurrent = (LPBYTE) lpvFile; memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // cabecera de archivo lpbCurrent += sizeof(BITMAPFILEHEADER); LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent; memcpy(lpbCurrent, m_lpBMIH, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // información lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // imagen de bits DWORD dwSizeImage = m_dwSizeImage; Empty(); m_dwSizeImage = dwSizeImage; m_nBmihAlloc = m_nImageAlloc = noAlloc; m_lpBMIH = lpBMIH; m_lpImage = lpbCurrent; m_hFile = hFile; m_hMap = hMap; m_lpvFile = lpvFile; ComputePaletteSize(m_lpBMIH->biBitCount); ComputeMetrics(); MakePalette(); return TRUE; }
/************************************************************************* * * \函数名称: * AttachMemory() * * \输入参数: * LPVOID lpvMem - 要关联的内存地址 * BOOL bMustDelete - 如果CDib类负责删除这个内存,标记为TRUE * - 默认值为FALSE * HGLOBAL hGlobal - 如果内存是通过Win32 GlobalAlloc得到的, * - 则CDib对象必须保存该句柄,这样,以后 * - 可以释放句柄。这里假设bMustDelete设置为TRUE * * \返回值: * BOOL - 如果成功,则为TRUE * * \说明: * 用内存中的DIB与已有的CDib对象关联。此内存可能是程序的资源,或者是可能是剪贴板 * 或者OLE数据对象内存。内存可能已经由CRT堆栈用new运算符分配了,或者可能已经由 * Windows堆栈用GlobalAlloc分配了。 * ************************************************************************ */ BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal) { // 首先释放已经分配的内存 Empty(); m_hGlobal = hGlobal; // bMustDelete为TRUE表示此CDib类分配的内存,负责删除 // 否则的设置信息头分配状态为noAlloc if(bMustDelete == FALSE) { m_nBmihAlloc = noAlloc; } else { m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc); } try { // 设置信息头指针 m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem; // 重新计算得到图象数据块的大小,并设置调色板的指针 ComputeMetrics(); // 计算调色板的尺寸 ComputePaletteSize(m_lpBMIH->biBitCount); // 设置图象数据指针 m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntries; // 如果调色板存在的话,读取它,并创建一个Windows调色板, // 并将调色板的句柄存放在数据成员中 MakePalette(); } // 错误处理 catch(CException* pe) { AfxMessageBox("AttachMemory error"); pe->Delete(); return FALSE; } // 返回 return TRUE; }
CDib::CDib(CSize size, int nBitCount, BOOL bInitialize) { m_pntOrigo = CPoint(0,0); //default origo m_hPalette = NULL; m_lpBMIH = NULL; m_lpImage = NULL; Empty(); ComputePaletteSize(nBitCount); m_lpBMIH = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableEntries]; m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER); m_lpBMIH->biWidth = size.cx; m_lpBMIH->biHeight = size.cy; m_lpBMIH->biPlanes = 1; m_lpBMIH->biBitCount = nBitCount; m_lpBMIH->biCompression = BI_RGB; m_lpBMIH->biSizeImage = 0; m_lpBMIH->biXPelsPerMeter = 0; m_lpBMIH->biYPelsPerMeter = 0; m_lpBMIH->biClrUsed = m_nColorTableEntries; m_lpBMIH->biClrImportant = m_nColorTableEntries; ComputeMetrics(); m_lpImage=(LPBYTE) new char[m_dwSizeImage]; if (bInitialize) { //make default palette from def256pal_x constants int i; switch (nBitCount) { case 1: SetPaletteEntry(0,0); //black SetPaletteEntry(1,RGB(255,255,255)); //white break; case 8: for (i=0; i<=255; i++) { SetPaletteEntry(i,RGB(def256pal_r[i],def256pal_g[i],def256pal_b[i])); } break; case 24: break; } memset(m_lpImage, 0, m_dwSizeImage); //initialize image bits to zero } MakePalette(); }
nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) { nsCOMPtr<nsIDOMNode> focusNode; nsresult rv = aSelection->GetFocusNode(getter_AddRefs(focusNode)); if (NS_FAILED(rv) || !focusNode) return nsnull; PRInt32 focusOffset; rv = aSelection->GetFocusOffset(&focusOffset); if (NS_FAILED(rv)) return nsnull; nsCOMPtr<nsIContent> contentNode = do_QueryInterface(focusNode); if (!contentNode) return nsnull; // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; nsCOMPtr<nsFrameSelection> frameSelection = GetFrameSelection(); if (!frameSelection) return nsnull; PRUint8 bidiLevel = frameSelection->GetCaretBidiLevel(); rv = GetCaretFrameForNodeOffset(contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, &theFrame, &theFrameOffset); if (NS_FAILED(rv) || !theFrame) return nsnull; nsPoint framePos(0, 0); rv = theFrame->GetPointFromOffset(theFrameOffset, &framePos); if (NS_FAILED(rv)) return nsnull; // now add the frame offset to the view offset, and we're done nscoord height = theFrame->GetSize().height; nscoord width = ComputeMetrics(theFrame, theFrameOffset, height).mCaretWidth; *aRect = nsRect(framePos.x, 0, width, height); return theFrame; }
CDib& CDib::operator=(const CDib& dib) { ASSERT(this != &dib); //beware of dib=dib if (dib.m_lpBMIH) { Empty(); //clear left operand (dib we are coping to) int headerSize = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*dib.m_nColorTableEntries; //copy header m_lpBMIH = (LPBITMAPINFOHEADER) new char[headerSize]; memcpy(m_lpBMIH,dib.m_lpBMIH,headerSize); //copy member variables ComputeMetrics(); ComputePaletteSize(dib.m_lpBMIH->biBitCount); MakePalette(); m_pntOrigo = dib.m_pntOrigo; //copy bits m_lpImage = (LPBYTE)new char[dib.m_dwSizeImage]; memcpy(m_lpImage,dib.m_lpImage,dib.m_dwSizeImage); } return *this; }
/************************************************************************* * * \函数名称: * CDib() * * \输入参数: * CSize size - 位图尺寸 * int nBitCount - 象素位数 * * \返回值: * 无 * * \说明: * 构造函数 * 根据给定的位图尺寸和象素位数构造CDib对象,并对信息头和调色板分配内存 * 但并没有给位图数据分配内存 * ************************************************************************ */ CDib::CDib(CSize size, int nBitCount) { m_hFile = NULL; m_hBitmap = NULL; m_hPalette = NULL; m_nBmihAlloc = m_nImageAlloc = noAlloc; Empty(); // 根据象素位数计算调色板尺寸 ComputePaletteSize(nBitCount); // 分配DIB信息头和调色板的内存 m_lpBMIH = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries]; // 设置信息头内存分配状态 m_nBmihAlloc = crtAlloc; // 设置信息头中的信息 m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER); m_lpBMIH->biWidth = size.cx; m_lpBMIH->biHeight = size.cy; m_lpBMIH->biPlanes = 1; m_lpBMIH->biBitCount = nBitCount; m_lpBMIH->biCompression = BI_RGB; m_lpBMIH->biSizeImage = 0; m_lpBMIH->biXPelsPerMeter = 0; m_lpBMIH->biYPelsPerMeter = 0; m_lpBMIH->biClrUsed = m_nColorTableEntries; m_lpBMIH->biClrImportant= m_nColorTableEntries; // 计算图象数据内存的大小,并设置此DIB的调色板的指针 ComputeMetrics(); // 将此DIB的调色板初始化为0 memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries); // 暂时不分配图象数据内存 m_lpImage = NULL; }
//////////////////////////////////////////////////////////////////////////////// // gfxDWriteFont gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry, const gfxFontStyle *aFontStyle, PRBool aNeedsBold, AntialiasOption anAAOption) : gfxFont(aFontEntry, aFontStyle, anAAOption) , mCairoFontFace(nsnull) , mCairoScaledFont(nsnull) , mNeedsOblique(PR_FALSE) , mNeedsBold(aNeedsBold) { gfxDWriteFontEntry *fe = static_cast<gfxDWriteFontEntry*>(aFontEntry); nsresult rv; DWRITE_FONT_SIMULATIONS sims = DWRITE_FONT_SIMULATIONS_NONE; if ((GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) && !fe->IsItalic()) { // For this we always use the font_matrix for uniformity. Not the // DWrite simulation. mNeedsOblique = PR_TRUE; } PRInt8 baseWeight, weightDistance; GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance); if (aNeedsBold) { sims |= DWRITE_FONT_SIMULATIONS_BOLD; } rv = fe->CreateFontFace(getter_AddRefs(mFontFace), sims); if (NS_FAILED(rv)) { mIsValid = PR_FALSE; return; } ComputeMetrics(); if (FontCanSupportHarfBuzz()) { mHarfBuzzShaper = new gfxHarfBuzzShaper(this); } }
CDib::CDib(const CDib& dib,CRect rect) //copy area of interest from dib { int headerSize = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*dib.m_nColorTableEntries; //copy header m_lpBMIH = (LPBITMAPINFOHEADER) new char[headerSize]; memcpy(m_lpBMIH,dib.m_lpBMIH,headerSize); //correct size m_lpBMIH->biWidth=rect.Width(); m_lpBMIH->biHeight=rect.Height(); m_lpBMIH->biSizeImage = 0; //compute member variables ComputeMetrics(); ComputePaletteSize(dib.m_lpBMIH->biBitCount); MakePalette(); m_pntOrigo = CPoint(0,0); //default origo //copy bits m_lpImage = (LPBYTE)new char[m_dwSizeImage]; for(int y=rect.top; y<=rect.bottom; y++){ for(int x=rect.left; x<=rect.right; x++){ SetPixel(CPoint(x-rect.left,y-rect.top),dib.GetPixel(CPoint(x,y))); } } }
BOOL CDib::Read(CFile* pFile) { // 1. leer cabecera de archivo para obtener el tamaño de la cabecera de info + tabla de colores // 2. leer cabecera de info (para obtener el tamaño de la imagen) y la tabla de colores // 3. leer la imagen // no se puede utilizar bfSize de la cabecera de info Empty(); int nCount, nSize; BITMAPFILEHEADER bmfh; try { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { //throw new CException; throw new std::exception; } if(bmfh.bfType != 0x4d42) { //throw new CException; throw new std::exception; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = m_nImageAlloc = crtAlloc; nCount = pFile->Read(m_lpBMIH, nSize); // cabecera de info y tabla de colores ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); m_lpImage = (LPBYTE) new char[m_dwSizeImage]; nCount = pFile->Read(m_lpImage, m_dwSizeImage); // sólo la imagen } catch(CException* pe) { AfxMessageBox(_T("Error de lectura")); pe->Delete(); return FALSE; } return TRUE; }
nsresult nsCaret::UpdateCaretRects(nsIFrame* aFrame, PRInt32 aFrameOffset) { NS_ASSERTION(aFrame, "Should have a frame here"); nsRect frameRect = aFrame->GetRect(); frameRect.x = 0; frameRect.y = 0; nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell); if (!presShell) return NS_ERROR_FAILURE; // If we got a zero-height frame we should figure out a height. We have to do // this after we've got an RC. if (frameRect.height == 0) { nsCOMPtr<nsIFontMetrics> fm; nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm)); if (fm) { nscoord ascent, descent; fm->GetMaxAscent(ascent); fm->GetMaxDescent(descent); frameRect.height = ascent + descent; // Place the caret on the baseline for inline frames, except when there is // a frame on the line with non-zero height. XXXmats why the exception? -- // I don't know but it seems to be necessary, see bug 503531. if (aFrame->GetStyleDisplay()->IsInlineOutside() && !FramesOnSameLineHaveZeroHeight(aFrame)) frameRect.y -= ascent; } } mCaretRect = frameRect; nsCOMPtr<nsISelection> domSelection = do_QueryReferent(mDomSelectionWeak); nsCOMPtr<nsISelectionPrivate> privateSelection = do_QueryInterface(domSelection); nsPoint framePos; // if cache in selection is available, apply it, else refresh it nsresult rv = privateSelection->GetCachedFrameOffset(aFrame, aFrameOffset, framePos); if (NS_FAILED(rv)) { mCaretRect.Empty(); return rv; } mCaretRect += framePos; Metrics metrics = ComputeMetrics(aFrame, aFrameOffset, mCaretRect.height); mCaretRect.width = metrics.mCaretWidth; // Clamp our position to be within our scroll frame. If we don't, then it // clips us, and we don't appear at all. See bug 335560. nsIFrame *scrollFrame = nsLayoutUtils::GetClosestFrameOfType(aFrame, nsGkAtoms::scrollFrame); if (scrollFrame) { // First, use the scrollFrame to get at the scrollable view that we're in. nsIScrollableFrame *sf = do_QueryFrame(scrollFrame); nsIFrame *scrolled = sf->GetScrolledFrame(); nsRect caretInScroll = mCaretRect + aFrame->GetOffsetTo(scrolled); // Now see if thet caret extends beyond the view's bounds. If it does, // then snap it back, put it as close to the edge as it can. nscoord overflow = caretInScroll.XMost() - scrolled->GetOverflowRectRelativeToSelf().width; if (overflow > 0) mCaretRect.x -= overflow; } // on RTL frames the right edge of mCaretRect must be equal to framePos const nsStyleVisibility* vis = aFrame->GetStyleVisibility(); if (NS_STYLE_DIRECTION_RTL == vis->mDirection) mCaretRect.x -= mCaretRect.width; return UpdateHookRect(presShell->GetPresContext(), metrics); }
/************************************************************************* * * \函数名称: * ReadSection() * * \输入参数: * CFile* pFile - 指向CFile对象的指针;对应的磁盘 * - 文件中包含DIB * CDC* pDC - 设备上下文指针 * * \返回值: * BOOL - 如果成功,则返回TRUE * * \说明: * 该函数从BMP文件中读取信息头,调用CreateDIBSection来分配图象内存,然后将 * 图象从该文件读入刚才分配的内存。如果你想从磁盘读取一个DIB,然后通过调用 * GDI函数编辑它的话,可以使用该函数。你可以用Write或CopyToMapFile将DIB写 * 回到磁盘 * ************************************************************************ */ BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */) { // 释放已经分配的内存 Empty(); // 临时变量 int nCount, nSize; BITMAPFILEHEADER bmfh; // 从文件中读取数据 try { // 读取文件头 nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { throw new CException; } // 如果文件类型部位"BM",则返回并进行相应错误处理 if(bmfh.bfType != 0x4d42) { throw new CException; } // 计算信息头加上调色板的大小,并分配相应的内存 nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = crtAlloc; m_nImageAlloc = noAlloc; // 读取信息头和调色板 nCount = pFile->Read(m_lpBMIH, nSize); // 如果图象为压缩格式,则不进行后续处理 if(m_lpBMIH->biCompression != BI_RGB) { throw new CException; } // 计算图象数据大小并设置调色板指针 ComputeMetrics(); // 计算调色板的表项数 ComputePaletteSize(m_lpBMIH->biBitCount); // 如果DIB中存在调色板,则创建一个Windows调色板 MakePalette(); // 将CDib对象的逻辑调色板选入设备上下文 UsePalette(pDC); // 创建一个DIB段,并分配图象内存 m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, (LPVOID*) &m_lpImage, NULL, 0); ASSERT(m_lpImage != NULL); // 从文件中读取图象数据 nCount = pFile->Read(m_lpImage, m_dwSizeImage); } // 错误处理 catch(CException* pe) { AfxMessageBox("ReadSection error"); pe->Delete(); return FALSE; } return TRUE; }
/************************************************************************* * * \函数名称: * Compress() * * \输入参数: * CDC* pDC - 设备上下文指针 * BOOL bCompress - TRUE对应于压缩的DIB,FALSE对应于不压缩的DIB * * \返回值: * BOOL - 如果成功,则返回TRUE * * \说明: * 该函数将DIB重新生成为压缩或者不压缩的DIB。在内部,它转换已有的DIB为DDB位图 * 然后生成一个新的压缩或者不压缩的DIB。压缩仅为4bpp和8bpp的DIB所支持。不能 * 压缩DIB段 * ************************************************************************ */ BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */) { // 判断是否为4bpp或者8bpp位图,否则,不进行压缩,返回FALSE if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE; // 如果为DIB段,也不能支持压缩,返回FALSE if(m_hBitmap) return FALSE; TRACE("Compress: original palette size = %d\n", m_nColorTableEntries); // 获得设备上下文句柄 HDC hdc = pDC->GetSafeHdc(); // 将此DIB的调色板选入设备上下文,并保存以前的调色板句柄 HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE); HBITMAP hBitmap; // 创建一个DDB位图,如果不成功,则返回FALSE if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE; // 计算信息头加上调色板的大小尺寸,并给它们分配内存 int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; // 将信息头和调色板拷贝到内存中 memcpy(lpBMIH, m_lpBMIH, nSize); // new header // 如果需要进行压缩,设置相应的信息,并创建压缩格式的DIB if(bCompress) { switch (lpBMIH->biBitCount) { case 4: lpBMIH->biCompression = BI_RLE4; break; case 8: lpBMIH->biCompression = BI_RLE8; break; default: ASSERT(FALSE); } // 设置位图数据指针为NULL,调用GetDIBits来得到压缩格式的DIB的尺寸 // 如果不能创建DIB,则进行相应的错误处理。 if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight, NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) { AfxMessageBox("Unable to compress this DIB"); // 删除临时变量,并释放已分配内存 ::DeleteObject(hBitmap); delete [] lpBMIH; // 重新将以前的调色板选入,并返回FALSE ::SelectPalette(hdc, hOldPalette, FALSE); return FALSE; } // 如果位图数据为空,则进行相应的错误处理 if (lpBMIH->biSizeImage == 0) { AfxMessageBox("Driver can't do compression"); // 删除临时变量,并释放已分配内存 ::DeleteObject(hBitmap); delete [] lpBMIH; // 重新将以前的调色板选入,并返回FALSE ::SelectPalette(hdc, hOldPalette, FALSE); return FALSE; } // 将位图数据尺寸赋值给类的成员变量 else { m_dwSizeImage = lpBMIH->biSizeImage; } } // 如果是解压缩,进行相应的处理 else { // 设置压缩格式为不压缩 lpBMIH->biCompression = BI_RGB; // 根据位图的宽度和高度计算位图数据内存的大小 DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32; if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) { dwBytes++; } dwBytes *= 4; // 将得到位图数据的大小尺寸保存在类的成员变量中 m_dwSizeImage = dwBytes * lpBMIH->biHeight; // 将位图数据内存的大小赋值给临时的信息头中的相应的变量 lpBMIH->biSizeImage = m_dwSizeImage; } // 再次调用GetDIBits来生成DIB数据 // 分配临时存放位图数据 LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage]; // 再次调用GetDIBits来生成DIB数据,注意此时位图数据指针不为空 VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight, lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)); TRACE("dib successfully created - height = %d\n", lpBMIH->biHeight); // 压缩转换完毕,进行相应的其他处理 // 删除临时的DDB位图 ::DeleteObject(hBitmap); // 释放原来的DIB分配的内存 Empty(); // 重新设置图象信息头和图象数据内存分配状态 m_nBmihAlloc = m_nImageAlloc = crtAlloc; // 重新定位信息头和图象数据指针 m_lpBMIH = lpBMIH; m_lpImage = lpImage; // 计算图象数据尺寸,并设置DIB中调色板的指针 ComputeMetrics(); // 计算DIB中调色板的尺寸 ComputePaletteSize(m_lpBMIH->biBitCount); // 如果DIB中调色板存在的话,读取并创建一个Windows调色板 MakePalette(); // 恢复以前的调色板 ::SelectPalette(hdc, hOldPalette, FALSE); TRACE("Compress: new palette size = %d\n", m_nColorTableEntries); // 返回 return TRUE; }
/************************************************************************* * * \函数名称: * CopyToMapFile() * * \输入参数: * const char* strPathname - 映射文件的路径名 * * \返回值: * BOOL - 如果成功,则为TRUE * * \说明: * 该函数可以创建一个新的内存映射文件,并将现有的CDib数据复制到该文件的内存 * 释放以前的所有内存。并关闭现有的所有内存映射文件。实际上,直到新文件 * 关闭的时候,才将这个数据写到磁盘,但是,当CDib对象被重复使用或被破坏 * 时,也会发生写磁盘操作 * ************************************************************************ */ BOOL CDib::CopyToMapFile(const char* strPathname) { BITMAPFILEHEADER bmfh; // 设置文件头信息 bmfh.bfType = 0x4d42; bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER); bmfh.bfReserved1= bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; // 创建接收数据的文件 HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ASSERT(hFile != INVALID_HANDLE_VALUE); // 计算文件的大小尺寸 int nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries + m_dwSizeImage; // 创建内存映射文件对象 HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NULL); DWORD dwErr = ::GetLastError(); ASSERT(hMap != NULL); // 映射整个文件 LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); ASSERT(lpvFile != NULL); // 临时文件指针 LPBYTE lpbCurrent = (LPBYTE) lpvFile; // 拷贝文件头信息到内存映射文件中 memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // 计算信息头在文件中的地址,并拷贝信息头信息 lpbCurrent += sizeof(BITMAPFILEHEADER); LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent; memcpy(lpbCurrent, m_lpBMIH, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // 计算调色板在文件中的地址,并拷贝调色板 lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // 暂时存放图象数据尺寸变量 DWORD dwSizeImage = m_dwSizeImage; // 释放一起分配的所有内存 Empty(); // 设置图象数据尺寸并设置内存分配状态 m_dwSizeImage = dwSizeImage; m_nBmihAlloc = m_nImageAlloc = noAlloc; // 信息头指针重新指向文件中的位置 m_lpBMIH = lpBMIH; // 图象数据指针重新指向文件中的数据地址 m_lpImage = lpbCurrent; // 设置文件句柄 m_hFile = hFile; // 设置映射对象句柄 m_hMap = hMap; // 设置映射文件指针 m_lpvFile = lpvFile; // 重新计算得到调色板尺寸 ComputePaletteSize(m_lpBMIH->biBitCount); // 重新计算图象数据块大小,并设置调色板指针 ComputeMetrics(); // 如果调色板存在的话,读取并创建一个Windows调色板 MakePalette(); // 返回 return TRUE; }
//----------------------------------------------------------------------------- nsresult nsCaret::GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *aDOMSel, nsRect *outCoordinates, PRBool *outIsCollapsed, nsIView **outView) { if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; if (!outCoordinates || !outIsCollapsed) return NS_ERROR_NULL_POINTER; nsCOMPtr<nsISelection> domSelection = aDOMSel; if (outView) *outView = nsnull; // fill in defaults for failure outCoordinates->x = -1; outCoordinates->y = -1; outCoordinates->width = -1; outCoordinates->height = -1; *outIsCollapsed = PR_FALSE; nsresult err = domSelection->GetIsCollapsed(outIsCollapsed); if (NS_FAILED(err)) return err; nsCOMPtr<nsIDOMNode> focusNode; err = domSelection->GetFocusNode(getter_AddRefs(focusNode)); if (NS_FAILED(err)) return err; if (!focusNode) return NS_ERROR_FAILURE; PRInt32 focusOffset; err = domSelection->GetFocusOffset(&focusOffset); if (NS_FAILED(err)) return err; nsCOMPtr<nsIContent> contentNode = do_QueryInterface(focusNode); if (!contentNode) return NS_ERROR_FAILURE; // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; nsCOMPtr<nsFrameSelection> frameSelection = GetFrameSelection(); if (!frameSelection) return NS_ERROR_FAILURE; PRUint8 bidiLevel = frameSelection->GetCaretBidiLevel(); err = GetCaretFrameForNodeOffset(contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, &theFrame, &theFrameOffset); if (NS_FAILED(err) || !theFrame) return err; nsPoint viewOffset(0, 0); nsIView *drawingView; // views are not refcounted GetViewForRendering(theFrame, aRelativeToType, viewOffset, &drawingView, outView); if (!drawingView) return NS_ERROR_UNEXPECTED; nsPoint framePos(0, 0); err = theFrame->GetPointFromOffset(theFrameOffset, &framePos); if (NS_FAILED(err)) return err; // we don't need drawingView anymore so reuse that; reset viewOffset values for our purposes if (aRelativeToType == eClosestViewCoordinates) { theFrame->GetOffsetFromView(viewOffset, &drawingView); if (outView) *outView = drawingView; } // now add the frame offset to the view offset, and we're done viewOffset += framePos; outCoordinates->x = viewOffset.x; outCoordinates->y = viewOffset.y; outCoordinates->height = theFrame->GetSize().height; outCoordinates->width = ComputeMetrics(theFrame, theFrameOffset, outCoordinates->height).mCaretWidth; return NS_OK; }
BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */) { // 1. crea un mapa de bits GDI a partir de un DIB existente // 2. crea un nuevo DIB a partir del mapa de bits GDI con compresión // 3. libera el DIB original // 4. pone el nuevo DIB en el objeto if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE; // sólo se admite la compresión para DIBs de 4 y 8 bpp if(m_hBitmap) return FALSE; // ¡no se puede comprimir una sección de DIB! TRACE("Compresión: tamaño original de la paleta = %d\n", m_nColorTableEntries); HDC hdc = pDC->GetSafeHdc(); HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE); HBITMAP hBitmap; // temporal if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE; int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; memcpy(lpBMIH, m_lpBMIH, nSize); // nueva cabecera if(bCompress) { switch (lpBMIH->biBitCount) { case 4: lpBMIH->biCompression = BI_RLE4; break; case 8: lpBMIH->biCompression = BI_RLE8; break; default: ASSERT(FALSE); } // llama a GetDIBits con un puntero de datos nulo para obtener el tamaño del DIB comprimido if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight, NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) { AfxMessageBox(_T("No se ha podido comprimir este DIB")); // probablemente un problema con la tabla de colores ::DeleteObject(hBitmap); delete [] lpBMIH; ::SelectPalette(hdc, hOldPalette, FALSE); return FALSE; } if (lpBMIH->biSizeImage == 0) { AfxMessageBox(_T("El controlador no puede realizar la compresión")); ::DeleteObject(hBitmap); delete [] lpBMIH; ::SelectPalette(hdc, hOldPalette, FALSE); return FALSE; } else { m_dwSizeImage = lpBMIH->biSizeImage; } } else { lpBMIH->biCompression = BI_RGB; // descomprimir // descubrir el tamaño de la imagen a partir de la anchura y altura del mapa de bits DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32; if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) { dwBytes++; } dwBytes *= 4; m_dwSizeImage = dwBytes * lpBMIH->biHeight; // sin compresión lpBMIH->biSizeImage = m_dwSizeImage; } // segunda llamada a GetDIBits para crear el DIB LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage]; VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight, lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)); TRACE("dib creado con éxito - altura = %d\n", lpBMIH->biHeight); ::DeleteObject(hBitmap); Empty(); m_nBmihAlloc = m_nImageAlloc = crtAlloc; m_lpBMIH = lpBMIH; m_lpImage = lpImage; ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); ::SelectPalette(hdc, hOldPalette, FALSE); TRACE("Compresión: nuevo tamaño de la paleta = %d\n", m_nColorTableEntries); return TRUE; }