Exemple #1
0
void SkeinWindow::StartEdit(Skein::Node* node, bool label)
{
  std::map<Skein::Node*,CRect>::const_iterator it = m_nodes.find(node);
  if (it != m_nodes.end())
  {
    CDibSection* back = m_bitmaps[BackUnplayed];
    CRect nodeRect = it->second;

    if (label)
    {
      nodeRect.InflateRect((node->GetLabelTextWidth()-nodeRect.Width())/2,0);
      nodeRect.InflateRect(m_fontSize.cx,0);
      nodeRect.top += (back->GetSize().cy/2);
      nodeRect.top -= (int)(0.12*m_fontSize.cy);
      nodeRect.top -= (int)(2.1*m_fontSize.cy);
      nodeRect.bottom = nodeRect.top + m_fontSize.cy+1;
      m_edit.SetFont(&m_labelFont);
    }
    else
    {
      nodeRect.DeflateRect(m_fontSize.cx*3,0);
      nodeRect.top += (back->GetSize().cy/2);
      nodeRect.top -= (int)(0.12*m_fontSize.cy);
      nodeRect.top -= (int)(0.5*m_fontSize.cy);
      nodeRect.bottom = nodeRect.top + m_fontSize.cy+1;
      m_edit.SetFont(theApp.GetFont(InformApp::FontDisplay));
    }

    m_edit.StartEdit(node,nodeRect,label);
  }
}
Exemple #2
0
void SkeinWindow::DrawLinePixel(CDC& dc, CDibSection& bitmap, int x, int y, double i,
  COLORREF fore)
{
  CSize size = bitmap.GetSize();
  if ((x < 0) || (y < 0) || (x >= size.cx) || (y >= size.cy))
    return;

  COLORREF back = bitmap.GetPixelColour(x,y);
  int r = (int)(((1.0-i)*GetRValue(fore))+(i*GetRValue(back)));
  int g = (int)(((1.0-i)*GetGValue(fore))+(i*GetGValue(back)));
  int b = (int)(((1.0-i)*GetBValue(fore))+(i*GetBValue(back)));
  bitmap.SetPixel(x,y,(r<<16)|(g<<8)|b);
}
CDibSection* FlatButton::GetImage(const char* name, const CSize& size, bool light)
{
  // Is the image in the cache?
  CString scaleName;
  scaleName.Format("%s-scaled",name);
  if (light)
    scaleName += "-light";
  CDibSection* dib = theApp.GetCachedImage(scaleName);
  if (dib != NULL)
    return dib;

  // Create the scaled image
  CDibSection* original_dib = theApp.GetCachedImage(name);
  CSize original_size = original_dib->GetSize();
  double scaleX = (double)size.cx / (double)original_size.cx;
  double scaleY = (double)size.cy / (double)original_size.cy;
  dib = theApp.CreateScaledImage(original_dib,scaleX,scaleY);
  if (light)
  {
    int sr, sg, sb, a;
    DWORD src;

    CSize size = dib->GetSize();
    for (int y = 0; y < size.cy; y++)
    {
      for (int x = 0; x < size.cx; x++)
      {
        src = dib->GetPixel(x,y);
        sb = src & 0xFF;
        src >>= 8;
        sg = src & 0xFF;
        src >>= 8;
        sr = src & 0xFF;
        src >>= 8;
        a = src & 0xFF;

        const double lighten = 0.4;
        sr = (int)(0xFF - ((0xFF - sr) * lighten));
        sg = (int)(0xFF - ((0xFF - sg) * lighten));
        sb = (int)(0xFF - ((0xFF - sb) * lighten));

        dib->SetPixel(x,y,(a<<24)|(sr<<16)|(sg<<8)|sb);
      }
    }
  }
  theApp.CacheImage(scaleName,dib);
  return dib;
}
Exemple #4
0
CDibSection* InformApp::CreateScaledImage(CDibSection* fromImage, double scaleX, double scaleY)
{
  // Work out the scaled image size
  CSize fromSize = fromImage->GetSize();
  CSize newSize((int)(fromSize.cx*scaleX),(int)(fromSize.cy*scaleY));

  // Create a scaled image
  CDibSection* newImage = new CDibSection();
  CDC* dc = AfxGetMainWnd()->GetDC();
  BOOL created = newImage->CreateBitmap(dc->GetSafeHdc(),newSize.cx,newSize.cy);
  ASSERT(created);
  AfxGetMainWnd()->ReleaseDC(dc);

  // Scale and stretch the image
  ScaleGfx(fromImage->GetBits(),fromSize.cx,fromSize.cy,
    newImage->GetBits(),newSize.cx,newSize.cy);
  return newImage;
}
Exemple #5
0
CDibSection* SkeinWindow::GetImage(const char* name, bool dark, bool blend)
{
  // Is the image in the cache?
  CString skeinName;
  skeinName.Format("%s-%s",name,dark ? "scaled-dark" : "scaled");
  CDibSection* dib = theApp.GetCachedImage(skeinName);
  if (dib != NULL)
    return dib;

  // Create the scaled image
  dib = theApp.CreateScaledImage(theApp.GetCachedImage(name),
    m_fontSize.cx*(1.4/7.0),m_fontSize.cy*(1.4/17.0));

  // Darken and alpha blend with the background colour
  if (dark)
    dib->Darken(0.7);
  if (blend)
    dib->AlphaBlend(theApp.GetColour(InformApp::ColourBack));

  theApp.CacheImage(skeinName,dib);
  return dib;
}
Exemple #6
0
CRect SourceWindow::PaintEdge(CDC& dcPaint, int y, int w, CDibSection* image, bool top)
{
  // Create a bitmap to draw into
  CDC dc;
  dc.CreateCompatibleDC(&dcPaint);
  CDibSection bitmap;
  CSize sz = image->GetSize();
  if (bitmap.CreateBitmap(dc.GetSafeHdc(),w,sz.cy) == FALSE)
    return CRect(0,0,0,0);
  bitmap.FillSolid(::GetSysColor(COLOR_BTNFACE));

  // Draw the torn edge
  int x = 0;
  while (x < w)
  {
    bitmap.AlphaBlend(image,x,0);
    x += sz.cx;
  }

  // Draw the arrow button
  CDibSection* btn = theApp.GetCachedImage("TearArrow");
  CRect btnRect(CPoint(w/2,sz.cy/2),CSize(0,0));
  CSize btnSize(btn->GetSize());
  btnRect.InflateRect(btnSize.cx/2,btnSize.cy/2);
  bitmap.AlphaBlend(btn,btnRect.left,btnRect.top,!top);

  // Copy the bitmap to the device context
  CBitmap* oldBitmap = CDibSection::SelectDibSection(dc,&bitmap);
  dcPaint.BitBlt(0,y,w,sz.cy,&dc,0,0,SRCCOPY);
  dc.SelectObject(oldBitmap);

  // Return a rectangle around the arrow button
  btnRect.InflateRect(btnSize.cx/2,btnSize.cy/2);
  btnRect.OffsetRect(0,y);
  return btnRect;
}
Exemple #7
0
CDibSection* SourceWindow::CreateTornImage(const char* inputImage, const char* outputName)
{
  CDibSection* input = theApp.GetCachedImage(inputImage);
  CSize inputSize = input->GetSize();

  CDibSection* output = new CDibSection();
  CDC* dc = AfxGetMainWnd()->GetDC();
  BOOL created = output->CreateBitmap(dc->GetSafeHdc(),inputSize.cx,inputSize.cy);
  ASSERT(created);
  AfxGetMainWnd()->ReleaseDC(dc);

  int br = GetRValue(m_back);
  int bg = GetGValue(m_back);
  int bb = GetBValue(m_back);

  int r, g, b, a;
  DWORD src;
  for (int y = 0; y < inputSize.cy; y++)
  {
    for (int x = 0; x < inputSize.cx; x++)
    {
      src = input->GetPixel(x,y);
      b = src & 0xFF;
      src >>= 8;
      g = src & 0xFF;
      src >>= 8;
      r = src & 0xFF;
      src >>= 8;
      a = src & 0xFF;

      r = (r * br) >> 8;
      g = (g * bg) >> 8;
      b = (b * bb) >> 8;
      output->SetPixel(x,y,(a<<24)|(r<<16)|(g<<8)|b);
    }
  }

  theApp.CacheImage(outputName,output);
  return output;
}
CDibSection::CDibSection(const CDibSection &dib)
	: hBitmap(0), Bits(0)
{
	if (Create(dib.Width(), dib.Height(), dib.Depth()))
		Copy(dib);
}
Exemple #9
0
CDibSection* InformApp::GetImage(const char* path)
{
  // Check if it's a PNG file
  CStdioFile imageFile;
  if (!imageFile.Open(path,CFile::modeRead|CFile::typeBinary))
    return 0;
  png_byte fileHeader[8];
  imageFile.Read(fileHeader,8);
  bool isPNG = (png_sig_cmp(fileHeader,0,8) == 0);

  if (isPNG)
  {
    // Prepare to read the PNG file
    png_structp png_ptr = png_create_read_struct
      (PNG_LIBPNG_VER_STRING,(png_voidp)NULL,NULL,NULL);
    if (png_ptr == NULL)
      return 0;
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
      png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
      return 0;
    }
    png_infop end_info = png_create_info_struct(png_ptr);
    if (end_info == NULL)
    {
      png_destroy_read_struct(&png_ptr,&info_ptr,(png_infopp)NULL);
      return 0;
    }

    // Set up the point to return to in case of error
    png_bytep* rowPointers = NULL;
    if (setjmp(png_jmpbuf(png_ptr)))
    {
      if (rowPointers)
        delete[] rowPointers;
      png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
      return 0;
    }

    png_init_io(png_ptr,imageFile.m_pStream);
    png_set_sig_bytes(png_ptr,8);
    png_read_info(png_ptr,info_ptr);

    // Get details of the image
    png_uint_32 width = png_get_image_width(png_ptr,info_ptr);
    png_uint_32 height = png_get_image_height(png_ptr,info_ptr);
    int bit_depth = png_get_bit_depth(png_ptr,info_ptr);
    int color_type = png_get_color_type(png_ptr,info_ptr);

    // Set up transforms to the required format
    if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
      png_set_palette_to_rgb(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
      png_set_expand_gray_1_2_4_to_8(png_ptr);
    if (png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS))
      png_set_tRNS_to_alpha(png_ptr);
    double gamma;
    if (png_get_gAMA(png_ptr,info_ptr,&gamma))
      png_set_gamma(png_ptr,2.2,gamma);
    if (bit_depth == 16)
      png_set_strip_16(png_ptr);
    if (bit_depth < 8)
      png_set_packing(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      png_set_gray_to_rgb(png_ptr);
    png_set_bgr(png_ptr);
    png_set_filler(png_ptr,0xFF,PNG_FILLER_AFTER);

    // Create a bitmap
    HDC dc = ::GetDC(NULL);
    CDibSection* dib = new CDibSection();
    BOOL created = dib->CreateBitmap(dc,width,height);
    ::ReleaseDC(NULL,dc);
    if (!created)
    {
      png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
      return NULL;
    }

    // Read in the image
    rowPointers = new png_bytep[height];
    for (int i = 0; i < (int)height; i++)
      rowPointers[i] = ((png_bytep)dib->GetBits())+(width*i*4);
    png_read_image(png_ptr,rowPointers);
    png_read_end(png_ptr,end_info);
    delete[] rowPointers;

    png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
    return dib;
  }
  else
  {
    imageFile.SeekToBegin();

    struct jpeg_decompress_struct info;
    struct JPEGErrorInfo error;

    // Initialize the error handling
    info.err = jpeg_std_error(&(error.base));
    error.base.error_exit = errorJPEGExit;
    error.base.output_message = outputJPEGMessage;
    if (setjmp(error.errorJump))
    {
      jpeg_destroy_decompress(&info);
      return NULL;
    }

    // Set up the decompression
    jpeg_create_decompress(&info);
    jpeg_stdio_src(&info,imageFile.m_pStream);

    // Read the image attributes
    jpeg_read_header(&info,TRUE);
    jpeg_calc_output_dimensions(&info);
    int width = info.output_width;
    int height = info.output_height;

    // Force RGB output
    info.out_color_space = JCS_RGB;

    // Create a bitmap
    HDC dc = ::GetDC(NULL);
    CDibSection* dib = new CDibSection();
    BOOL created = dib->CreateBitmap(dc,width,height);
    ::ReleaseDC(NULL,dc);
    if (!created)
    {
      jpeg_destroy_decompress(&info);
      return NULL;
    }

    // Get an output buffer
    JSAMPARRAY buffer = (*info.mem->alloc_sarray)
      ((j_common_ptr)&info,JPOOL_IMAGE,width*3,1);

    // Read in the image
    jpeg_start_decompress(&info);
    while ((int)info.output_scanline < height)
    {
      jpeg_read_scanlines(&info,buffer,1);

      BYTE* pixelRow = ((BYTE*)dib->GetBits())+(width*(info.output_scanline-1)*4);
      for (int i = 0; i < width; i++)
      {
        pixelRow[(i*4)+0] = (*buffer)[(i*3)+2];
        pixelRow[(i*4)+1] = (*buffer)[(i*3)+1];
        pixelRow[(i*4)+2] = (*buffer)[(i*3)+0];
        pixelRow[(i*4)+3] = 0xFF;
      }
    }
    jpeg_finish_decompress(&info);
    jpeg_destroy_decompress(&info);
    return dib;
  }
}
void FlatButton::DrawItem(LPDRAWITEMSTRUCT dis)
{
  CDC* dcPaint = CDC::FromHandle(dis->hDC);
  CRect rectPaint(dis->rcItem);
  bool disabled = (dis->itemState & ODS_DISABLED) != 0;

  // Create a bitmap to paint into
  CDC dc;
  dc.CreateCompatibleDC(dcPaint);
  CRect rect(0,0,rectPaint.Width(),rectPaint.Height());
  CDibSection bitmap;
  if (bitmap.CreateBitmap(dc.GetSafeHdc(),rect.Width(),rect.Height()) == FALSE)
    return;
  CBitmap* oldBitmap = CDibSection::SelectDibSection(dc,&bitmap);

  // Draw the background
  if (dis->itemState & ODS_SELECTED)
  {
    // Get the bitmap to indicate a selected button
    CBitmap selectBitmap;
    selectBitmap.LoadBitmap(IDR_FLAT_SELECT);
    CDC selectDC;
    selectDC.CreateCompatibleDC(&dc);
    CBitmap* oldBitmap = selectDC.SelectObject(&selectBitmap);

    // Get the bitmap's dimensions
    BITMAP bitmapInfo;
    selectBitmap.GetBitmap(&bitmapInfo);

    // Stretch the bitmap into the selected item's background
    dc.StretchBlt(0,0,rect.Width(),rect.Height(),
      &selectDC,0,0,bitmapInfo.bmWidth,bitmapInfo.bmHeight,SRCCOPY);
    selectDC.SelectObject(oldBitmap);
  }
  else
    dc.FillSolidRect(rect,::GetSysColor(COLOR_BTNFACE));

  // Get the button's text
  CString text;
  GetWindowText(text);

  // Draw the contents of the button
  if (text == "?<")
  {
    CRect imageRect(rect);
    if (imageRect.Width() > imageRect.Height())
      imageRect.DeflateRect((imageRect.Width() - imageRect.Height())/2,0);
    int gap = imageRect.Height()/6;
    imageRect.DeflateRect(gap,gap);
    CDibSection* dib = GetImage("Arrow-left",imageRect.Size(),disabled);
    bitmap.AlphaBlend(dib,gap,gap,FALSE);
  }
  else if (text == "?>")
  {
    CRect imageRect(rect);
    if (imageRect.Width() > imageRect.Height())
      imageRect.DeflateRect((imageRect.Width() - imageRect.Height())/2,0);
    int gap = imageRect.Height()/6;
    imageRect.DeflateRect(gap,gap);
    CDibSection* dib = GetImage("Arrow-right",imageRect.Size(),disabled);
    bitmap.AlphaBlend(dib,gap,gap,FALSE);
  }

  // Draw the separator
  CPen shadowPen(PS_SOLID,0,::GetSysColor(COLOR_BTNSHADOW));
  dc.SelectObject(shadowPen);
  int gap = rect.Height()/6;
  dc.MoveTo(rect.right-1,gap);
  dc.LineTo(rect.right-1,rect.bottom-gap);

  // Draw the control from the bitmap
  dcPaint->BitBlt(rectPaint.left,rectPaint.top,rectPaint.Width(),rectPaint.Height(),&dc,0,0,SRCCOPY);
  dc.SelectObject(oldBitmap);
}
void TranscriptWindow::OnDraw(CDC* pDC)
{
    CRect clientRect;
    GetClientRect(clientRect);

    CDC dc;
    dc.CreateCompatibleDC(pDC);

    // Create an off-screen bitmap for drawing
    CDibSection bitmap;
    if (bitmap.CreateBitmap(pDC->GetSafeHdc(),clientRect.Width(),clientRect.Height()) == FALSE)
        return;
    CBitmap* oldBitmap = CDibSection::SelectDibSection(dc,&bitmap);

    dc.SetBkMode(TRANSPARENT);
    dc.FillSolidRect(clientRect,theApp.GetColour(InformApp::ColourBack));

    if (m_skein->IsActive())
    {
        CFont* oldFont = dc.SelectObject(theApp.GetFont(InformApp::FontDisplay));
        CPen linePen(PS_SOLID,1,theApp.GetColour(InformApp::ColourBorder));
        CPen* oldPen = dc.SelectObject(&linePen);

        int y = 0;
        int yinput = m_layout.fontSize.cy+(2*m_layout.margin.cy);

        // If the transcript is taller than the window, work out the drawing origin
        if (GetHeight() > clientRect.Height())
        {
            SCROLLINFO scroll;
            ::ZeroMemory(&scroll,sizeof scroll);
            scroll.cbSize = sizeof scroll;
            GetScrollInfo(SB_VERT,&scroll);
            y -= scroll.nPos;
        }

        // Clear the map of visible buttons and expected texts
        m_buttons.clear();
        m_expecteds.clear();

        // Loop over the transcript nodes
        std::deque<NodeLayout>::const_iterator nodeIt;
        for (nodeIt = m_layout.nodes.begin(); nodeIt != m_layout.nodes.end(); ++nodeIt)
        {
            const NodeLayout& nl = *nodeIt;

            // Is this node visible?
            CRect nodeRect(0,y,1,y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy)+1);
            CRect intersection;
            if (intersection.IntersectRect(nodeRect,clientRect) == FALSE)
            {
                // Not visible, so increase the y position and try the next node
                y += yinput+nl.height+(2*m_layout.margin.cy);
                continue;
            }

            // Get the text associated with the node
            const CStringW& transcript = nl.node->GetTranscriptText();
            const CStringW& expected = nl.node->GetExpectedText();
            const CStringW& line = nl.node->GetLine();

            // Fill in the background of the input line
            dc.FillSolidRect(0,y+1,clientRect.Width(),yinput,
                             theApp.GetColour(InformApp::ColourTransInput));

            // Fill in the background of the transcript text
            COLORREF back;
            if (transcript.IsEmpty())
                back = theApp.GetColour(InformApp::ColourTransUnset);
            else
            {
                back = theApp.GetColour(nl.node->GetChanged() ?
                                        InformApp::ColourTransDiffers : InformApp::ColourTransSame);
            }
            CRect backRect(0,y+yinput,m_layout.columnWidth,
                           y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
            dc.FillSolidRect(backRect,back);

            // Fill in the background of the expected text
            if (expected.IsEmpty())
                back = theApp.GetColour(InformApp::ColourTransUnset);
            else
            {
                switch (nl.node->GetDiffers())
                {
                case Skein::Node::ExpectedSame:
                    back = theApp.GetColour(InformApp::ColourTransSame);
                    break;
                case Skein::Node::ExpectedNearlySame:
                    back = RGB(255,255,127);
                    break;
                case Skein::Node::ExpectedDifferent:
                    back = theApp.GetColour(InformApp::ColourTransDiffers);
                    break;
                default:
                    ASSERT(FALSE);
                    back = theApp.GetColour(InformApp::ColourTransDiffers);
                    break;
                }
            }
            backRect.OffsetRect(m_layout.columnWidth+1,0);
            dc.FillSolidRect(backRect,Brighter(back));

            // If this is the first node in the transcript, draw a horizontal line at the top
            if (nl.node == m_skein->GetRoot())
            {
                dc.MoveTo(0,y);
                dc.LineTo(clientRect.Width(),y);
            }

            // Draw a horizontal line below the node's input
            dc.MoveTo(0,y+yinput);
            dc.LineTo(clientRect.Width(),y+yinput);

            // Draw a final horizontal line below the text boxes
            dc.MoveTo(0,y+yinput+nl.height+(2*m_layout.margin.cy));
            dc.LineTo(clientRect.Width(),y+yinput+nl.height+(2*m_layout.margin.cy));

            // Draw a dividing line between the two text boxes
            dc.MoveTo(m_layout.columnWidth,y+yinput);
            dc.LineTo(m_layout.columnWidth,y+yinput+nl.height+(2*m_layout.margin.cy));

            // If this is the last played knot in the skein, draw a yellow border around it
            if (nl.node == m_skeinPlayed)
            {
                CRect backRect(0,y,clientRect.Width(),
                               y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
                DrawInsideRect(dc,backRect,CSize(m_layout.margin.cx*3/4,m_layout.margin.cy*7/8),
                               theApp.GetColour(InformApp::ColourTransPlayed));
            }

            // If this is the knot selected in the skein, draw a blue border around it
            if (nl.node == m_skeinSelected)
            {
                CRect backRect(0,y,clientRect.Width(),
                               y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
                DrawInsideRect(dc,backRect,CSize(m_layout.margin.cx*3/8,m_layout.margin.cy*7/16),
                               theApp.GetColour(InformApp::ColourTransSelect));
            }

            // Draw the buttons at the end of the input line, and store their positions
            int btnHeight = m_layout.fontSize.cy+m_layout.margin.cy;
            CRect btnRect(
                CPoint(clientRect.Width()-(m_layout.margin.cy/2),y+(m_layout.margin.cy/2)),
                CSize(0,btnHeight));
            btnRect = DrawButton(dc,btnRect,false,"Show knot",Button(nl.node,ButtonShow),true);
            btnRect.right = btnRect.left-(m_layout.margin.cy/2);
            DrawButton(dc,btnRect,false,"Play to here",Button(nl.node,ButtonPlay),true);

            // Write the node's input
            dc.SetTextColor(theApp.GetColour(InformApp::ColourText));
            CRect textRect(m_layout.margin.cx,y+m_layout.margin.cy,
                           btnRect.left-m_layout.margin.cx,y+yinput);
            theOS.DrawText(&dc,line,line.GetLength(),textRect,DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS);

            // Draw the 'bless' button, and store its position
            y += yinput;
            btnRect.right = m_layout.columnWidth;
            btnRect.top = y+(((nl.height+(2*m_layout.margin.cy))-btnHeight)/2);
            btnRect.bottom = btnRect.top+btnHeight;
            DrawButton(dc,btnRect,true,"Bless",Button(nl.node,ButtonBless),nl.node->CanBless());

            // Write the text in the text boxes
            textRect = CRect(m_layout.margin.cx,y+m_layout.margin.cy,
                             m_layout.columnWidth-m_layout.centreMargin,y+m_layout.margin.cy+nl.height);
            DrawText(dc,textRect,transcript,nl.node->GetTranscriptDiffs());
            textRect.OffsetRect(m_layout.columnWidth+m_layout.centreMargin-m_layout.margin.cx,0);
            DrawText(dc,textRect,expected,nl.node->GetExpectedDiffs());
            textRect.InflateRect(theApp.MeasureFont(m_edit.GetFont()).cx/4,0);
            m_expecteds.push_back(std::make_pair(backRect,Expected(nl.node,textRect)));

            // Advance the y position
            y += nl.height+(2*m_layout.margin.cy);
        }

        dc.SelectObject(oldPen);
        dc.SelectObject(oldFont);

        // If the edit window is visible, exclude the area under it to reduce flicker
        if (m_edit.IsWindowVisible())
        {
            CRect editRect;
            m_edit.GetWindowRect(&editRect);
            ScreenToClient(&editRect);
            pDC->ExcludeClipRect(editRect);
        }
    }

    // Copy to the on-screen device context
    pDC->BitBlt(0,0,clientRect.Width(),clientRect.Height(),&dc,0,0,SRCCOPY);
    dc.SelectObject(oldBitmap);
}
Exemple #12
0
void SkeinWindow::DrawNodeBack(Skein::Node* node, CDC& dc, CDibSection& bitmap, const CPoint& centre,
  int width, CDibSection* back)
{
  // Create a device context for the source bitmap
  CDC dcFrom;
  dcFrom.CreateCompatibleDC(&dc);
  CBitmap* fromBitmap = CDibSection::SelectDibSection(dcFrom,back);

  int y = centre.y-(back->GetSize().cy/2)+(int)(0.12*m_fontSize.cy);
  int edgeWidth = m_fontSize.cx*4;

  // Draw the rounded edges of the background
  dc.BitBlt(centre.x-(width/2)-edgeWidth,y,edgeWidth,back->GetSize().cy,
    &dcFrom,0,0,SRCCOPY);
  dc.BitBlt(centre.x+(width/2),y,edgeWidth,back->GetSize().cy,
    &dcFrom,back->GetSize().cx-edgeWidth,0,SRCCOPY);

  // Draw the rest of the background
  {
    int x = centre.x-(width/2);
    while (x < centre.x+(width/2))
    {
      int w = back->GetSize().cx-(2*edgeWidth);
      ASSERT(w > 0);
      if (x+w > centre.x+(width/2))
        w = centre.x+(width/2)-x;
      dc.BitBlt(x,y,w,back->GetSize().cy,&dcFrom,edgeWidth,0,SRCCOPY);
      x += w;
    }
  }

  // Draw the "differs badge", if needed
  if ((node->GetDiffers() != Skein::Node::ExpectedSame) && (node->GetExpectedText().IsEmpty() == FALSE))
  {
    CDibSection* badge = m_bitmaps[DiffersBadge];
    CSize badgeSize = badge->GetSize();
    bitmap.AlphaBlend(badge,
      centre.x+(width/2)+edgeWidth-badgeSize.cx,y+back->GetSize().cy-badgeSize.cy);
  }

  // Draw the label background, if needed
  if (ShowLabel(node))
  {
    CDibSection::SelectDibSection(dcFrom,m_bitmaps[BackAnnotate]);
    int labelWidth = node->GetLabelTextWidth();
    int labelHeight = (int)(0.9*back->GetSize().cy);
    int labelY = y - (int)(1.8*m_fontSize.cy);

    dc.BitBlt(centre.x-(labelWidth/2)-edgeWidth,labelY,edgeWidth,labelHeight,
      &dcFrom,0,0,SRCCOPY);
    dc.BitBlt(centre.x+(labelWidth/2),labelY,edgeWidth,labelHeight,
      &dcFrom,back->GetSize().cx-edgeWidth,0,SRCCOPY);

    int x = centre.x-(labelWidth/2);
    while (x < centre.x+(labelWidth/2))
    {
      int w = back->GetSize().cx-(2*edgeWidth);
      if (x+w > centre.x+(labelWidth/2))
        w = centre.x+(labelWidth/2)-x;
      dc.BitBlt(x,labelY,w,labelHeight,&dcFrom,edgeWidth,0,SRCCOPY);
      x += w;
    }
  }

  dcFrom.SelectObject(fromBitmap);

  // Store the node's size and position
  m_nodes[node] = CRect(
    CPoint(centre.x-(width/2)-edgeWidth,y),
    CSize(width+(2*edgeWidth),back->GetSize().cy));
}
Exemple #13
0
void SkeinWindow::OnDraw(CDC* pDC)
{
  // Clear out any previous node positions
  m_nodes.clear();

  // Get the dimensions of the window
  CRect client;
  GetClientRect(client);

  // Create a memory device context
  CDC dc;
  dc.CreateCompatibleDC(pDC);

  // Create a memory bitmap
  CDibSection bitmap;
  if (bitmap.CreateBitmap(pDC->GetSafeHdc(),client.Width(),client.Height()) == FALSE)
    return;
  CBitmap* oldBitmap = CDibSection::SelectDibSection(dc,&bitmap);
  CFont* oldFont = dc.SelectObject(theApp.GetFont(InformApp::FontDisplay));
  CPoint origin = pDC->GetViewportOrg();

  // Clear the background
  dc.FillSolidRect(client,theApp.GetColour(InformApp::ColourBack));

  if (m_skein->IsActive())
  {
    // Redo the layout if needed
    m_skein->Layout(dc,&m_labelFont,m_fontSize.cx*10,false);

    // Work out the position of the centre of the root node
    CPoint rootCentre(origin);
    rootCentre.y += (int)(m_fontSize.cy*2.2);

    // If there is no horizontal scrollbar, centre the root node
    BOOL horiz, vert;
    CheckScrollBars(horiz,vert);
    if (horiz)
      rootCentre.x += GetTotalSize().cx/2;
    else
      rootCentre.x += client.Width()/2;

    // Get the end node of the transcript
    Skein::Node* transcriptEnd = (Skein::Node*)
      GetParentFrame()->SendMessage(WM_TRANSCRIPTEND);

    // Draw all nodes
    DrawNodeTree(m_skein->GetRoot(),transcriptEnd,dc,bitmap,client,
      CPoint(0,0),rootCentre,m_fontSize.cy*5);

    // If the edit window is visible, exclude the area under it to reduce flicker
    if (m_edit.IsWindowVisible())
    {
      CRect editRect;
      m_edit.GetWindowRect(&editRect);
      ScreenToClient(&editRect);
      editRect -= pDC->GetViewportOrg();
      pDC->ExcludeClipRect(editRect);
    }
  }

  // Draw the memory bitmap on the window's device context
  pDC->BitBlt(-origin.x,-origin.y,client.Width(),client.Height(),&dc,0,0,SRCCOPY);

  // Restore the original device context settings
  dc.SelectObject(oldFont);
  dc.SelectObject(oldBitmap);
}