Ejemplo n.º 1
0
/*
 * Read enough of the stream to initialize the SkGifCodec.
 * Returns a bool representing success or failure.
 *
 * @param codecOut
 * If it returned true, and codecOut was not nullptr,
 * codecOut will be set to a new SkGifCodec.
 *
 * @param gifOut
 * If it returned true, and codecOut was nullptr,
 * gifOut must be non-nullptr and gifOut will be set to a new
 * GifFileType pointer.
 *
 * @param stream
 * Deleted on failure.
 * codecOut will take ownership of it in the case where we created a codec.
 * Ownership is unchanged when we returned a gifOut.
 *
 */
bool SkGifCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType** gifOut) {
    SkAutoTDelete<SkStream> streamDeleter(stream);

    // Read gif header, logical screen descriptor, and global color table
    SkAutoTCallVProc<GifFileType, CloseGif> gif(open_gif(stream));

    if (nullptr == gif) {
        gif_error("DGifOpen failed.\n");
        return false;
    }

    // Read through gif extensions to get to the image data.  Set the
    // transparent index based on the extension data.
    uint32_t transIndex;
    SkCodec::Result result = ReadUpToFirstImage(gif, &transIndex);
    if (kSuccess != result){
        return false;
    }

    // Read the image descriptor
    if (GIF_ERROR == DGifGetImageDesc(gif)) {
        return false;
    }
    // If reading the image descriptor is successful, the image count will be
    // incremented.
    SkASSERT(gif->ImageCount >= 1);

    if (nullptr != codecOut) {
        SkISize size;
        SkIRect frameRect;
        if (!GetDimensions(gif, &size, &frameRect)) {
            gif_error("Invalid gif size.\n");
            return false;
        }
        bool frameIsSubset = (size != frameRect.size());

        // Determine the recommended alpha type.  The transIndex might be valid if it less
        // than 256.  We are not certain that the index is valid until we process the color
        // table, since some gifs have color tables with less than 256 colors.  If
        // there might be a valid transparent index, we must indicate that the image has
        // alpha.
        // In the case where we must support alpha, we have the option to set the
        // suggested alpha type to kPremul or kUnpremul.  Both are valid since the alpha
        // component will always be 0xFF or the entire 32-bit pixel will be set to zero.
        // We prefer kPremul because we support kPremul, and it is more efficient to use
        // kPremul directly even when kUnpremul is supported.
        SkAlphaType alphaType = (transIndex < 256) ? kPremul_SkAlphaType : kOpaque_SkAlphaType;

        // Return the codec
        // kIndex is the most natural color type for gifs, so we set this as
        // the default.
        SkImageInfo imageInfo = SkImageInfo::Make(size.width(), size.height(), kIndex_8_SkColorType,
                alphaType);
        *codecOut = new SkGifCodec(imageInfo, streamDeleter.detach(), gif.detach(), transIndex,
                frameRect, frameIsSubset);
    } else {
        SkASSERT(nullptr != gifOut);
        streamDeleter.detach();
        *gifOut = gif.detach();
    }
    return true;
}
Ejemplo n.º 2
0
template <typename T> void MenuWidget<T>::Render()
{
    Color BackgroundColor(1.0, 1.0, 1.0);
    Color BorderColor(0.3, 0.3, 0.3);

    /*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
    {
    }
    else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
    {
    	BorderColor[0] = 0.898;
    	BorderColor[1] = 0.765;
    	BorderColor[2] = 0.396;
    }
    else
    {
    }*/
    // HACK, TODO: Make this a single DRY const
    if (HasTypingFocus())
    {
        BorderColor[0] = 0.898;
        BorderColor[1] = 0.765;
        BorderColor[2] = 0.396;
    }

    // TODO: Think if I should outsource the entire rendering code for more generality
    // Draw list
    {
        UpdateDimensions();		// LATER: Optimize by not repeating this calculation each time, only when something changes?

        if (m_Entries.empty())
        {
            BackgroundColor[0] = 234 / 255.0;
            BackgroundColor[1] = 233 / 255.0;
            BackgroundColor[2] = 190 / 255.0;
        }

        DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

        // TEST
        auto Spot = m_Entries.end();
        if (   nullptr != m_TypingModule
                && !m_TypingModule->GetString().empty())
        {
            for (auto & Pointer : GetGestureRecognizer().GetConnected())
            {
                if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
                {
                    Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
                    Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

                    Spot = m_Entries.begin() + (LocalPosition.Y() / lineHeight);
                }
            }
        }

        OpenGLStream OpenGLStream(GetPosition());
        //for (auto & Entry : m_Entries)
        for (auto Entry = m_Entries.begin(); m_Entries.end() != Entry; ++Entry)
        {
            if (Entry == Spot)
                OpenGLStream << endl;

            if (Entry - m_Entries.begin() == m_SelectedEntryId)
            {
                if (HasTypingFocus())
                    DrawBox(GetPosition() + Vector2n(0, static_cast<sint32>((Entry - m_Entries.begin() + (Entry >= Spot)) * lineHeight)), Vector2n(GetDimensions().X(), lineHeight), m_SelectedColor, m_SelectedColor);
                else
                    DrawBox(GetPosition() + Vector2n(0, static_cast<sint32>((Entry - m_Entries.begin() + (Entry >= Spot)) * lineHeight)), Vector2n(GetDimensions().X(), lineHeight), m_UnfocusedSelectedColor, m_UnfocusedSelectedColor);
            }

            OpenGLStream << *Entry << endl;
        }
    }
}
void ConceptStringBoxWidget::Render()
{
	Color BackgroundColor(1.0, 1.0, 1.0);
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/
	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}

	/*glBegin(GL_QUADS);
		glVertex2d(m_Position.X(), m_Position.Y());
		glVertex2d(m_Position.X(), m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y());
	glEnd();*/
	DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

	glColor3d(0, 0, 0);
	OpenGLStream OpenGLStream(GetPosition());
	//OpenGLStream << m_Content.substr(0, m_CaretPosition);
	// TODO: Optimize this somehow?
	OpenGLStream << decltype(m_Content)(m_Content.begin(), m_Content.begin() + m_CaretPosition);

	// TEST
	if (!m_TypingModule.GetString().empty())
	{
		for (auto & Pointer : GetGestureRecognizer().GetConnected())
		{
			if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
			{
				//Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
				//Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

				//auto ConceptId = FindOrCreateConcept(Entry);

				OpenGLStream << m_TypingModule.GetString();
			}
		}
	}

	Vector2n CaretPosition = OpenGLStream.GetCaretPosition();

	//OpenGLStream << m_Content.substr(m_CaretPosition);
	// TODO: Optimize this somehow?
	OpenGLStream << decltype(m_Content)(m_Content.begin() + m_CaretPosition, m_Content.end());

	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		// Draw caret
		//if (static_cast<int>(glfwGetTime() * 2) % 2)
		{
			glPushMatrix();
			glTranslated(CaretPosition.X(), CaretPosition.Y(), 0);
			glColor3d(0, 0, 0);
			glBegin(GL_QUADS);
				glVertex2d(-1, 0);
				glVertex2d(-1, lineHeight);
				glVertex2d(+1, lineHeight);
				glVertex2d(+1, 0);
			glEnd();
			glPopMatrix();
		}
	}
}
Ejemplo n.º 4
0
void CTimeOSD::update(time_t time_show)
{
	time_t tDisplayTime;
	static time_t oldDisplayTime = 0;
	char cDisplayTime[8 + 1];
	fb_pixel_t color1, color2;
	
	GetDimensions();

	//printf("CTimeOSD::update time %ld\n", time_show);
	
	if(!visible)
		return;

	if(m_mode == MODE_ASC) 
	{
		color1 = COL_MENUCONTENT_PLUS_0;
		color2 = COL_MENUCONTENT;
	} 
	else 
	{
		color1 = COL_MENUCONTENTSELECTED_PLUS_0;
		color2 = COL_MENUCONTENTSELECTED;
		
		if(!time_show) 
			time_show = 1;
	}

	if(time_show) 
	{
		m_time_show = time_show;
		tDisplayTime = m_time_show;
	} 
	else 
	{
		if(m_mode == MODE_ASC) 
		{
			tDisplayTime = m_time_show + (time(NULL) - m_time_dis);
		} 
		else 
		{
			tDisplayTime = m_time_show + (m_time_dis - time(NULL));
		}
	}

	if(tDisplayTime < 0)
		tDisplayTime = 0;

	if(tDisplayTime != oldDisplayTime) 
	{
		oldDisplayTime = tDisplayTime;
		strftime(cDisplayTime, 9, "%T", gmtime(&tDisplayTime));
		
		// time shadow
		frameBuffer->paintBoxRel(m_xend - m_width - 10 + SHADOW_OFFSET, m_y + SHADOW_OFFSET, m_width + 10, m_height, COL_INFOBAR_SHADOW_PLUS_0);

		// time window
		frameBuffer->paintBoxRel(m_xend - m_width - 10, m_y, m_width + 10, m_height, color1 );

		// time
		g_Font[TIMEOSD_FONT]->RenderString(m_xend - m_width - 5, m_y + m_height, m_width + 5, cDisplayTime, color2);
	}
	
	frameBuffer->blit();
}
Ejemplo n.º 5
0
template <typename T> void ListWidget<T>::Render()
{
	Color BackgroundColor(1.0, 1.0, 1.0);
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/

	// TODO: Think if I should outsource the entire rendering code for more generality
	// Draw list
	{
		UpdateDimensions();		// LATER: Optimize by not repeating this calculation each time, only when something changes?

		if (m_List.empty())
		{
			BackgroundColor[0] = 234 / 255.0;
			BackgroundColor[1] = 233 / 255.0;
			BackgroundColor[2] = 190 / 255.0;
		}

		DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

		// TEST
		auto Spot = m_List.end();
		if (!m_TypingModule.GetString().empty())
		{
			for (auto & Pointer : GetGestureRecognizer().GetConnected())
			{
				if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
				{
					Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
					Vector2n LocalPosition(GlobalToLocal(GlobalPosition));

					Spot = m_List.begin() + (LocalPosition.Y() / lineHeight);
				}
			}
		}

		OpenGLStream OpenGLStream(GetPosition());
		for (auto ListEntry = m_List.begin(); m_List.end() != ListEntry; ++ListEntry)
		{
			if (ListEntry == Spot)
				OpenGLStream << endl;

			OpenGLStream << *ListEntry << endl;
		}
	}

#if DECISION_LIST_WIDGET_IS_COMPOSITE
	CompositeWidget::Render();
#endif
}
Ejemplo n.º 6
0
int
vtkVisItUtility::CalculateGhostIdFromNonGhost(vtkDataSet *ds, const int id,
                                              const bool forCell)
{
    int retVal = id;
    int type = ds->GetDataObjectType();

    if (type == VTK_STRUCTURED_GRID ||
        type == VTK_RECTILINEAR_GRID ||
        ds->GetFieldData()->GetArray("vtkOriginalDimensions") != NULL) 
    {
        int dimX, dimY, dims[3]; 
        int ijk[3] = { -1, -1, -1};
        GetDimensions(ds, dims);
        if (dims[0] == -1 || dims[1] == -1 || dims[2] == -1)
        {
            return id;
        }
        vtkIntArray *realDims = 
            (vtkIntArray*)ds->GetFieldData()->GetArray("avtRealDims");
        if (realDims != NULL)
        {
            dimX = realDims->GetValue(1) - realDims->GetValue(0);
            dimY = realDims->GetValue(3) - realDims->GetValue(2);
            if (!forCell)
            {
                dimX++;
                dimY++;
            }
        }
        else 
        {
            if (forCell)
            {
                dimX = (dims[0]-1 > 0 ? dims[0]-1 : 1);
                dimY = (dims[1]-1 > 0 ? dims[1]-1 : 1);
            }
            else
            {
                dimX = (dims[0] == 0 ? 1 : dims[0]);
                dimY = (dims[1] == 0 ? 1 : dims[1]);
            }
        }
        if (dims[2] == 1)
        {
            ijk[0] = (id % dimX);
            ijk[1] = (id / dimX);
            ijk[2] = 0;
        }
        else 
        {
            ijk[0] = (id % dimX);          
            ijk[1] = ((id / dimX) % dimY);
            ijk[2] = (id / (dimX * dimY));
        }

        ijk[0] = ijk[0] < 0 ? 0 : ijk[0];
        ijk[1] = ijk[1] < 0 ? 0 : ijk[1];
        ijk[2] = ijk[2] < 0 ? 0 : ijk[2];

        if (realDims != NULL)
        {
            ijk[0] += realDims->GetValue(0);
            ijk[1] += realDims->GetValue(2);
            ijk[2] += realDims->GetValue(4);
        }

        int nElsI = dims[0];
        int nElsJ = dims[1];
        if (forCell)
        {
            nElsI -= 1;
            nElsJ -= 1;
        }
        retVal = ijk[0] +
                 ijk[1] * nElsI +  
                 ijk[2] * nElsI * nElsJ;
    }
    return retVal;
}
void
avtResampleFilter::ResampleInput(void)
{
    int  i, j, k;

    avtDataset_p output = GetTypedOutput();
    double bounds[6] = { 0, 0, 0, 0, 0, 0 };
    bool is3D = GetBounds(bounds);

    debug4 << "Resampling over space: " << bounds[0] << ", " << bounds[1]
           << ": " << bounds[2] << ", " << bounds[3] << ": " << bounds[4]
           << ", " << bounds[5] << endl;
    
    //
    // Our resampling leaves some invalid values in the data range.  The
    // easiest way to bypass this is to get the data range from the input and
    // pass it along (since resampling does not change it in theory).
    //
    double range[2];
    if (GetInput()->GetInfo().GetAttributes().ValidActiveVariable())
    {
        GetDataExtents(range);
        output->GetInfo().GetAttributes().GetDesiredDataExtents()->Set(range);
    }

    avtViewInfo view;
    double scale[3];
    CreateViewFromBounds(view, bounds, scale);

    //
    // What we want the width, height, and depth to be depends on the
    // attributes.
    //
    int width, height, depth;
    GetDimensions(width, height, depth, bounds, is3D);

    //
    // If there are no variables, then just create the mesh and exit.
    //
    bool thereAreNoVariables = 
          (GetInput()->GetInfo().GetAttributes().GetNumberOfVariables() <= 0);
    if (thereAreNoVariables)
    {
        if (PAR_Rank() == 0)
        {
            vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth,
                                      0, width, 0, height, cellCenteredOutput, is3D);
            avtDataTree_p tree = new avtDataTree(rg, 0);
            rg->Delete();
            SetOutputDataTree(tree);
        }
        else
        {
            //
            // Putting in a NULL data tree can lead to seg faults, etc.
            //
            avtDataTree_p dummy = new avtDataTree();
            SetOutputDataTree(dummy);
        }

        return;
    }

    //
    // World space is a right-handed coordinate system.  Image space (as used
    // in the sample point extractor) is a left-handed coordinate system.
    // This is because large X is at the right and large Y is at the top.
    // The z-buffer has the closest points at z=0, so Z is going away from the
    // screen ===> left handed coordinate system.  If we reflect across X,
    // then this will account for the difference between the coordinate 
    // systems.
    //
    scale[0] *= -1.;

    //
    // We don't want an Update to go all the way up the pipeline, so make
    // a terminating source corresponding to our input.
    //
    avtDataset_p ds;
    avtDataObject_p dObj = GetInput();
    CopyTo(ds, dObj);
    avtSourceFromAVTDataset termsrc(ds);

    //
    // The sample point extractor expects everything to be in image space.
    //
    avtWorldSpaceToImageSpaceTransform trans(view, scale);
    trans.SetInput(termsrc.GetOutput());

    bool doKernel = 
        (GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() == 0);
    avtSamplePointExtractor extractor(width, height, depth);
    extractor.SendCellsMode(false);
    extractor.Set3DMode(is3D);
    extractor.SetInput(trans.GetOutput());
    if (doKernel)
        extractor.SetKernelBasedSampling(true);
    avtSamplePoints_p samples = extractor.GetTypedOutput();

    //
    // If the selection this filter exists to create has already been handled,
    // or if there are no pieces for this processor to process, then we can skip
    // execution. But, take care to emulate the same collective
    // calls other processors may make before returning.
    //
    if (GetInput()->GetInfo().GetAttributes().GetSelectionApplied(selID))
    {
        debug1 << "Bypassing Resample operator because database plugin "
                  "claims to have applied the selection already" << endl;

        SetOutputDataTree(GetInputDataTree());

        // we can save a lot of time if we know everyone can bypass
        if (UnifyMaximumValue(0) == 0)
            return;

        // here is some dummied up code to match collective calls below
        int effectiveVars = samples->GetNumberOfRealVariables();
        double *ptrtmp = new double[width*height*depth];
        for (int jj = 0; jj < width*height*depth; jj++)
            ptrtmp[jj] = -FLT_MAX;
        for (i = 0 ; i < effectiveVars ; i++)
            Collect(ptrtmp, width*height*depth);
        delete [] ptrtmp;
        return;
    }
    else
    {
        UnifyMaximumValue(1);
    }

    //
    //
    // PROBLEM SIZED WORK OCCURS BEYOND THIS POINT
    // If you add (or remove) collective calls below this point, make sure to
    // put matching sequence into bypass code above
    //
    //

    avtSamplePointCommunicator communicator;
    avtImagePartition partition(width, height, PAR_Size(), PAR_Rank());
    communicator.SetImagePartition(&partition);
    bool doDistributedResample = false;
#ifdef PARALLEL
    doDistributedResample = atts.GetDistributedResample();
#endif

    if (doDistributedResample)
    {
        partition.SetShouldProduceOverlaps(true);
        avtDataObject_p dob;
        CopyTo(dob, samples);
        communicator.SetInput(dob);
        samples = communicator.GetTypedOutput();
    }

    // Always set up an arbitrator, even if user selected random.
    bool arbLessThan = !atts.GetUseArbitrator() || atts.GetArbitratorLessThan();
    std::string arbName = atts.GetArbitratorVarName();
    if (arbName == "default")
        arbName = primaryVariable;
    extractor.SetUpArbitrator(arbName, arbLessThan);

    //
    // Since this is Execute, forcing an update is okay...
    //
    samples->Update(GetGeneralContract());

    if (samples->GetInfo().GetValidity().HasErrorOccurred())
    {
        GetOutput()->GetInfo().GetValidity().ErrorOccurred();
        GetOutput()->GetInfo().GetValidity().SetErrorMessage(
                          samples->GetInfo().GetValidity().GetErrorMessage());
    }

    //
    // Create a rectilinear dataset that is stretched according to the 
    // original bounds.
    //
    int width_start  = 0;
    int width_end    = width;
    int height_start = 0;
    int height_end   = height;
    if (doDistributedResample)
    {
        partition.GetThisPartition(width_start, width_end, height_start, 
                                   height_end);
        width_end += 1;
        height_end += 1;
    }

    //
    // If we have more processors than domains, we have to handle that
    // gracefully.  Communicate how many variables there are so that those
    // that don't have data can play well.
    //
    int realVars  = samples->GetNumberOfRealVariables();
    int numArrays = realVars;
    if (doKernel)
        numArrays++;
    vtkDataArray **vars = new vtkDataArray*[numArrays];
    for (i = 0 ; i < numArrays ; i++)
    {
        vars[i] = vtkDoubleArray::New();
        if (doKernel && (i == numArrays-1))
            vars[i]->SetNumberOfComponents(1);
        else
        {
            vars[i]->SetNumberOfComponents(samples->GetVariableSize(i));
            vars[i]->SetName(samples->GetVariableName(i).c_str());
        }
    }

    if (doKernel)
        samples->GetVolume()->SetUseKernel(true);

    avtImagePartition *ip = NULL;
    if (doDistributedResample)
        ip = &partition;

    // We want all uncovered regions to get the default value.  That is
    // what the first argument of GetVariables is for.  But if the
    // default value is large, then it will screw up the collect call below,
    // which uses MPI_MAX for an all reduce.  So give uncovered regions very
    // small values now (-FLT_MAX) and then replace them later.
    double defaultPlaceholder = -FLT_MAX;
    samples->GetVolume()->GetVariables(defaultPlaceholder, vars, 
                                       numArrays, ip);

    if (!doDistributedResample)
    {
        //
        // Collect will perform the parallel collection.  Does nothing in
        // serial.  This will only be valid on processor 0.
        //
        for (i = 0 ; i < numArrays ; i++)
        {
            double *ptr = (double *) vars[i]->GetVoidPointer(0);
            Collect(ptr, vars[i]->GetNumberOfComponents()*width*height*depth);
        }
    }
    
    // Now replace the -FLT_MAX's with the default value.  (See comment above.)
    for (i = 0 ; i < numArrays ; i++)
    {
        int numTups = vars[i]->GetNumberOfComponents()
                    * vars[i]->GetNumberOfTuples();
        if (numTups > 0)
        {
            double *ptr = (double *) vars[i]->GetVoidPointer(0);
            for (j = 0 ; j < numTups ; j++)
                ptr[j] = (ptr[j] == defaultPlaceholder 
                                 ? atts.GetDefaultVal() 
                                 : ptr[j]);
        }
    }
   
    bool iHaveData = false;
    if (doDistributedResample)
        iHaveData = true;
    if (PAR_Rank() == 0)
        iHaveData = true;
    if (height_end > height)
        iHaveData = false;
    if (iHaveData)
    {
        vtkRectilinearGrid *rg = CreateGrid(bounds, width, height, depth,
                                        width_start, width_end, height_start,
                                        height_end, cellCenteredOutput, is3D);

        if (doKernel)
        {
            double min_weight = avtPointExtractor::GetMinimumWeightCutoff();
            vtkDataArray *weights = vars[numArrays-1];
            int numVals = weights->GetNumberOfTuples();
            for (i = 0 ; i < realVars ; i++)
            {
                for (j = 0 ; j < vars[i]->GetNumberOfComponents() ; j++)
                {
                    for (k = 0 ; k < numVals ; k++)
                    {
                        double weight = weights->GetTuple1(k);
                        if (weight <= min_weight)
                            vars[i]->SetComponent(k, j, atts.GetDefaultVal());
                        else
                            vars[i]->SetComponent(k, j, 
                                         vars[i]->GetComponent(k, j) / weight);
                    }
                }
            }
        }

        //
        // Attach these variables to our rectilinear grid.
        //
        for (i = 0 ; i < realVars ; i++)
        {
            const char *varname = vars[i]->GetName();
            if (strcmp(varname, primaryVariable) == 0)
            {
                if (vars[i]->GetNumberOfComponents() == 3)
                    if (cellCenteredOutput)
                        rg->GetCellData()->SetVectors(vars[i]);
                    else
                        rg->GetPointData()->SetVectors(vars[i]);
                else if (vars[i]->GetNumberOfComponents() == 1)
                {
                    if (cellCenteredOutput)
                    {
                        rg->GetCellData()->AddArray(vars[i]);
                        rg->GetCellData()->SetScalars(vars[i]);
                    }
                    else
                    {
                        rg->GetPointData()->AddArray(vars[i]);
                        rg->GetPointData()->SetScalars(vars[i]);
                    }
                }
                else
               {
                    if (cellCenteredOutput)
                        rg->GetCellData()->AddArray(vars[i]);
                    else
                        rg->GetPointData()->AddArray(vars[i]);
               }
            }
            else
            {
                if (cellCenteredOutput)
                    rg->GetCellData()->AddArray(vars[i]);
                else
                    rg->GetPointData()->AddArray(vars[i]);
            }
        }

        avtDataTree_p tree = new avtDataTree(rg, 0);
        rg->Delete();
        SetOutputDataTree(tree);
    }
    else
    {
        //
        // Putting in a NULL data tree can lead to seg faults, etc.
        //
        avtDataTree_p dummy = new avtDataTree();
        SetOutputDataTree(dummy);
    }

    for (i = 0 ; i < numArrays ; i++)
    {
        vars[i]->Delete();
    }
    delete [] vars;
}
Ejemplo n.º 8
0
void GUIWindow::SetTitleBarDimensions(int xOffset, int yOffset, int width, int height)
{
	m_titleBar->SetDimensions(xOffset, GetDimensions().m_height + yOffset, width, height);
}
Ejemplo n.º 9
0
void
vtkVisItUtility::GetLogicalIndices(vtkDataSet *ds, const bool forCell, const int ID, 
                                   int ijk[3], const bool global,
                                   const bool adjustForGhosts)
{ 
    int dimX, dimY, dims[3], base[3] = {0, 0, 0};

    GetDimensions(ds, dims);
    if (dims[0] == -1 || dims[1] == -1 || dims[2] == -1)
    {
        ijk[0] = ijk[1] = ijk[2] = -1;
        return;
    }

    if (global)
    {
        vtkIntArray *bi = (vtkIntArray*)ds->GetFieldData()->GetArray("base_index");
        if (bi)
        {
            base[0] = bi->GetValue(0);
            base[1] = bi->GetValue(1);
            base[2] = bi->GetValue(2);
        }
    }

    if (adjustForGhosts)
    {
        vtkIntArray *realDims = 
            (vtkIntArray*)ds->GetFieldData()->GetArray("avtRealDims");
        if (realDims)
        {
            base[0] -= realDims->GetValue(0);
            base[1] -= realDims->GetValue(2);
            base[2] -= realDims->GetValue(4);
        }
    }

    if (forCell)
    {
        dimX = (dims[0]-1 > 0 ? dims[0]-1 : 1);
        dimY = (dims[1]-1 > 0 ? dims[1]-1 : 1);
    }
    else
    {
        dimX = (dims[0] == 0 ? 1 : dims[0]);
        dimY = (dims[1] == 0 ? 1 : dims[1]);
    }

    if (dims[2] == 1)
    {
        ijk[0] = (ID % dimX) + base[0];
        ijk[1] = (ID / dimX) + base[1];
        ijk[2] = 0;
    }
    else 
    {
        ijk[0] = (ID % dimX)          + base[0];
        ijk[1] = ((ID / dimX) % dimY) + base[1];
        ijk[2] = (ID / (dimX * dimY)) + base[2];
    }

    ijk[0] = ijk[0] < 0 ? 0 : ijk[0];
    ijk[1] = ijk[1] < 0 ? 0 : ijk[1];
    ijk[2] = ijk[2] < 0 ? 0 : ijk[2];
}
Ejemplo n.º 10
0
/**
 * Use the height data in the grid and a colormap fill a bitmap with colors.
 * Any undefined heixels in the source will be fill with red (255,0,0).
 *
 * \param pBM			The bitmap to be colored.
 * \param table			The table of colors.
 * \param fMin, fMax	The range of valid elevation values expect in the input.
 * \param nodata		The color to use for NODATA areas, where there are no elevation values.
 * \param progress_callback If supplied, this function will be called back
 *			with a value of 0 to 100 as the operation progresses.
 *
 * \return true if any invalid elevation values were encountered.
 */
bool vtHeightFieldGrid3d::ColorDibFromTable(vtBitmapBase *pBM,
	   std::vector<RGBi> &table, float fMin, float fMax, const RGBAi &nodata,
	   bool progress_callback(int))
{
	VTLOG1(" ColorDibFromTable:");
	int w = pBM->GetWidth();
	int h = pBM->GetHeight();
	int depth = pBM->GetDepth();
	int gw, gh;
	GetDimensions(gw, gh);

	VTLOG(" dib size %d x %d, grid %d x %d.. ", w, h, gw, gh);

	bool bExact = (w == gw && h == gh);
	double ratiox = (double)(gw-1)/(w-1), ratioy = (double)(gh-1)/(h-1);

	float fRange = fMax - fMin;
	uint iGranularity = table.size()-1;
	bool has_invalid = false;
	RGBi nodata_24bit(nodata.r, nodata.g, nodata.b);
	double x, y;
	float elev;

	// now iterate over the texels
	for (int i = 0; i < w; i++)
	{
		if (progress_callback != NULL)
		{
			if ((i&7) == 0)
				progress_callback(i * 100 / w);
		}
		x = i * ratiox;		// find corresponding location in height grid

		for (int j = 0; j < h; j++)
		{
			y = j * ratioy;

			if (bExact)
				elev = GetElevation(i, j);
			else
				elev = GetInterpolatedElevation(x, y);
			if (elev == INVALID_ELEVATION)
			{
				if (depth == 32)
					pBM->SetPixel32(i, h-1-j, nodata);
				else
					pBM->SetPixel24(i, h-1-j, nodata_24bit);
				has_invalid = true;
				continue;
			}
			uint table_entry = (uint) ((elev - fMin) / fRange * iGranularity);
			if (table_entry > iGranularity-1)
				table_entry = iGranularity-1;
			if (depth == 32)
				pBM->SetPixel32(i, h-1-j, table[table_entry]);
			else
				pBM->SetPixel24(i, h-1-j, table[table_entry]);
		}
	}
	VTLOG("Done.\n");
	return has_invalid;
}
Ejemplo n.º 11
0
/* Core code contributed by Kevin Behilo, 2/20/04.
 *
 * Possible TODO: add code to soften and blend shadow edges
 *  (see aliasing comments in source).
 *
 * Definite TODO: the whole thing can be sped up by precalculating the
 *  surface normals once.  In fact that should be placed in a separate Shading
 *  Context, so that it could be re-used for quickly re-shading multiple times.
 */
void vtHeightFieldGrid3d::ShadowCastDib(vtBitmapBase *pBM, const FPoint3 &light_dir,
	float fLightFactor, float fAmbient, bool progress_callback(int))
{
	int w = pBM->GetWidth();
	int h = pBM->GetHeight();

	int gw, gh;
	GetDimensions(gw, gh);

	// Compute area that we will sample for shading, bounded by the texel
	//  centers, which are 1/2 texel in from the grid extents.
	DPoint2 texel_size(m_EarthExtents.Width() / w, m_EarthExtents.Height() / h);
	DRECT texel_area = m_EarthExtents;
	texel_area.Grow(-texel_size.x/2, -texel_size.y/2);
	DPoint2 texel_base(texel_area.left, texel_area.bottom);

	bool b8bit = (pBM->GetDepth() == 8);
	int i, j;

	// These values are hardcoded here but could be exposed in the GUI
	float sun =  0.7f;

	// If we have light that's pointing UP, rather than down at the terrain,
	//  then it's only going to take a really long time to produce a
	//  completely dark terrain.  We can catch this case up front.
	if (light_dir.y > 0)
	{
		for (i = 0; i < w; i++)
		{
			for (j = 0; j < h; j++)
			{
				if (b8bit)
					pBM->ScalePixel8(i, j, fAmbient);
				else
					pBM->ScalePixel24(i, j, fAmbient);
			}
		}
		return;
	}

	// Create array to hold flags
	LightMap lightmap(w, h);

	// This factor is used when applying shading to non-shadowed areas to
	// try and keep the "contrast" down to a min. (still get "patches" of
	// dark/light spots though).
	// It is initialized to 1.0, because in case there are no shadows at all
	//  (such as at noon) we still need a reasonable value.
	float darkest_shadow = 1.0;

	// For the vector used to cast shadows, we need it in grid coordinates,
	//  which are (Column,Row) where Row is north.  But the direction passed
	//  in uses OpenGL coordinates where Z is south.  So flip Z.
	FPoint3 grid_light_dir = light_dir;
	grid_light_dir.z = -grid_light_dir.z;

	// Scale the light vector such that the X or Z component (whichever is
	//  larger) is 1.  This is will serve as our direction vector in grid
	//  coordinates, when drawing a line across the grid to cast the shadow.
	//
	// Code adapted from aaron_torpy:
	// http://www.geocities.com/aaron_torpy/algorithms.htm
	//
	float f, HScale;
	if ( fabs(grid_light_dir.x) > fabs(grid_light_dir.z) )
	{
		HScale = m_fXStep;
		f = fabs(light_dir.x);
	}
	else
	{
		HScale = m_fZStep;
		f = fabs(light_dir.z);
	}
	grid_light_dir /= f;

	int i_init, i_final, i_incr;
	int j_init, j_final, j_incr;
	if (grid_light_dir.x > 0)
	{
		i_init=0;
		i_final=w;
		i_incr=1;
	}
	else
	{
		i_init=w-1;
		i_final=-1;
		i_incr=-1;
	}
	if (grid_light_dir.z > 0)
	{
		j_init=0;
		j_final=h;
		j_incr=1;
	}
	else
	{
		j_init=h-1;
		j_final=-1;
		j_incr=-1;
	}

	// First pass: find each point that it is in shadow.
	DPoint2 pos;
	float shadowheight, elevation;
	FPoint3 normal;
	FPoint3 p3;
	int x, z;
	float shade;

	for (j = j_init; j != j_final; j += j_incr)
	{
		if (progress_callback != NULL)
		{
			if ((j&7) == 0)
				progress_callback(abs(j-j_init) * 100 / h);
		}
		for (i = i_init; i != i_final; i += i_incr)
		{
			pos = GridPos(texel_base, texel_size, i, j);
			FindAltitudeOnEarth(pos, shadowheight, true);

			if (shadowheight == INVALID_ELEVATION)
			{
				// set a flag so we won't visit this one again
				lightmap.Set(i, j, 1);
				continue;
			}

			bool Under_Out = false;
			for (int k = 1; Under_Out == false; k++)
			{
				x = (int) (i + grid_light_dir.x*k + 0.5f);
				z = (int) (j + grid_light_dir.z*k + 0.5f);
				shadowheight += grid_light_dir.y * HScale;

				if ((x<0) || (x>w-1) || (z<0) || (z>h-1))
				{
					Under_Out = true; // Out of the grid
					break;
				}

				pos = GridPos(texel_base, texel_size, x, z);
				FindAltitudeOnEarth(pos, elevation, true);

				// skip holes in the grid
				if (elevation == INVALID_ELEVATION)
					continue;

				if (elevation > shadowheight)
				{
					if (k>1)
						Under_Out = true; // Under the terrain
					break;
				}

				// Combine color and shading.
				// Only do shadow if we have not shaded this i,j before.
				if (lightmap.Get(x,z) < 1)
				{
					// 3D elevation query to get slope
					m_Conversion.ConvertFromEarth(pos, p3.x, p3.z);
					FindAltitudeAtPoint(p3, p3.y, true, 0, &normal);

					//*****************************************
					// Here the Sun(r, g, b) = 0 because we are in the shade
					// therefore I(r, g, b) = Amb(r, g, b) * (0.5*N[z] + 0.5)

				//	shade =  sun*normal.Dot(-light_direction) + fAmbient * (0.5f*normal.y + 0.5f);
					shade =  fAmbient * (0.5f*normal.y + 0.5f);
					//*****************************************
					//*****************************************
					if (darkest_shadow > shade)
						darkest_shadow = shade;

					//Rather than doing the shading at this point we may want to
					//simply save the value into the LightMap array. Then apply
					//some anti-aliasing or edge softening algorithm to the LightMap.
					//Once that's done, apply the whole LightMap to the DIB.
					if (b8bit)
						pBM->ScalePixel8(x, h-1-z, shade);
					else
						pBM->ScalePixel24(x, h-1-z, shade);

					//set a flag to show that this texel has been shaded.
					// (or set to value of the shading - see comment above)
					lightmap.Set(x, z, lightmap.Get(x, z)+1);
				}
			}
		} //for i
	} //for j

	// For dot-product lighting, we use the normal 3D vector, only inverted
	//  so that we can compare it to the upward-pointing ground normals.
	FPoint3 inv_light_dir = -light_dir;

	// Second pass.  Now we are going to loop through the LightMap and apply
	//  the full lighting formula to each texel that has not been shaded yet.
	for (j = 0; j < h; j++)
	{
		if (progress_callback != NULL)
		{
			if ((j&7) == 0)
				progress_callback(j * 100 / h);
		}
		for (i = 0; i < w; i++)
		{
			if (lightmap.Get(i, j) > 0)
				continue;

			pos = GridPos(texel_base, texel_size, i, j);

			// 2D elevation query to check for holes in the grid
			FindAltitudeOnEarth(pos, elevation, true);
			if (elevation == INVALID_ELEVATION)
				continue;

			// 3D elevation query to get slope
			m_Conversion.ConvertFromEarth(pos, p3.x, p3.z);
			FindAltitudeAtPoint(p3, p3.y, true, 0, &normal);

			//*****************************************
			//*****************************************
			//shade formula based on:
			//http://www.geocities.com/aaron_torpy/algorithms.htm#calc_intensity

			// The Amb value was arbitrarily chosen
			// Need to experiment more to determine the best value
			// Perhaps calculating Sun(r, g, b) and Amb(r, g, b) for a
			//  given time of day (e.g. warmer colors close to sunset)
			// or give control to user since textures will differ

			// I(r, g, b) = Sun(r, g, b) * scalarprod(N, v) + Amb(r, g, b) * (0.5*N[z] + 0.5)
			shade = sun * normal.Dot(inv_light_dir);

			// It's a reasonable assuption that an angle of 45 degrees is
			//  sufficient to fully illuminate the ground.
			shade /= .7071f;

			// Now add ambient component
			shade += fAmbient * (0.5f*normal.y + 0.5f);

			// Maybe clipping values can be exposed to the user as well.
			// Clip - don't shade down below lowest ambient level
			if (shade < darkest_shadow)
				shade = darkest_shadow;
			else if (shade > 1.2f)
				shade = 1.2f;

			// Push the value of 'shade' toward 1.0 by the fLightFactor factor.
			// This means that fLightFactor=0 means no lighting, 1 means full lighting.
			float diff = 1 - shade;
			diff = diff * (1 - fLightFactor);
			shade += diff;

			// Rather than doing the shading at this point we may want to
			// simply save the value into the LightMap array. Then apply
			// some anti-aliasing or edge softening algorithm to the LightMap.
			// Once that's done, apply the whole LightMap to the DIB.
			// LightMap[I][J]= shade; // set to value of the shading - see comment above)
			if (b8bit)
				pBM->ScalePixel8(i, h-1-j, shade);
			else
				pBM->ScalePixel24(i, h-1-j, shade);
		}
	}

	// Possible TODO: Apply edge softening algorithm (?)
}
Ejemplo n.º 12
0
	void Rectangle::OnRender(uint32 timePassed) {
		const auto dimensions = GetDimensions();
		Utils::Vector2 position = GetScreenPosition();
		const auto pRenderTarget = sD3DMgr.GetRenderTarget();

		if (GetDropShadow()) {
			if (m_shadowTexture == nullptr)
				CreateShadowTexture();

			const RECT *pClipRect = GetGlobalInterface()->ClipStack.Top();
			if (pClipRect != nullptr) {
				RECT newClipRect = *pClipRect;
				if (m_shadowDirection.x < 0.0f)
					newClipRect.left += static_cast<LONG>(m_shadowDirection.x);
				else
					newClipRect.right += static_cast<LONG>(m_shadowDirection.x);

				if (m_shadowDirection.y < 0.0f)
					newClipRect.top += static_cast<LONG>(m_shadowDirection.y);
				else
					newClipRect.bottom += static_cast<LONG>(m_shadowDirection.y);

				pRenderTarget->SetClippingArea(&newClipRect);
			}

			std::array<D3DXCOLOR, 4> gradient;
			gradient.fill(CalculateAbsoluteColor(0xAA000000));

			pRenderTarget->DrawBlurredSprite(
				position + m_shadowDirection,
				m_shadowTexture,
				dimensions,
				gradient);

			if (pClipRect != nullptr)
				pRenderTarget->SetClippingArea(pClipRect);

			const auto pSprite = sD3DMgr.GetSprite();
			if (pSprite != nullptr) {
				Utils::Vector3 position3 = position;
				pSprite->Begin(D3DXSPRITE_ALPHABLEND);
				pSprite->Draw(m_shadowTexture, nullptr, nullptr, &position3, CalculateAbsoluteColor(0xFFFFFFFF));
				pSprite->End();
			}
		}
		else {
			float4 horizRounding = GetHorizontalRoundings();
			float4 vertRounding = GetVerticalRoundings();
			const auto gradient = CalculateAbsoluteColor(GetGradientColors());

			if (((horizRounding._1 != 0.0f && vertRounding._1 != 0.0f) ||
				 (horizRounding._2 != 0.0f && vertRounding._2 != 0.0f) ||
				 (horizRounding._3 != 0.0f && vertRounding._3 != 0.0f) ||
				 (horizRounding._4 != 0.0f && vertRounding._4 != 0.0f)))
			{
				pRenderTarget->FillRoundedRectangle(
					position,
					dimensions,
					horizRounding,
					vertRounding,
					gradient);
			}
			else
				pRenderTarget->FillRectangle(position, dimensions, gradient);
		}
	}
Ejemplo n.º 13
0
void TextFieldWidget::Render()
{
	//Color BackgroundColor(1.0, 1.0, 1.0);
	Color BackgroundColor = m_BackgroundColor;
	Color BorderColor(0.3, 0.3, 0.3);

	/*if (CheckHover(WidgetManager) && CheckActive(WidgetManager))
	{
	}
	else if ((CheckHover(WidgetManager) && !CheckAnyActive(WidgetManager)) || (!CheckHover(WidgetManager) && CheckActive(WidgetManager)))
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}
	else
	{
	}*/
	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		BorderColor[0] = 0.898;
		BorderColor[1] = 0.765;
		BorderColor[2] = 0.396;
	}

	/*glBegin(GL_QUADS);
		glVertex2d(m_Position.X(), m_Position.Y());
		glVertex2d(m_Position.X(), m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y() + 30);
		glVertex2d(m_Position.X() + 30, m_Position.Y());
	glEnd();*/
	DrawAroundBox(GetPosition(), GetDimensions(), BackgroundColor, BorderColor);

	// TEST
	auto ContentWithInsertion = m_Content;
	if (!m_TypingModule.GetString().empty())
	{
		for (auto & Pointer : GetGestureRecognizer().GetConnected())
		{
			if (Pointer::VirtualCategory::POINTING == Pointer->GetVirtualCategory())
			{
				Vector2n GlobalPosition(Pointer->GetPointerState().GetAxisState(0).GetPosition(), Pointer->GetPointerState().GetAxisState(1).GetPosition());
				Vector2n LocalPosition(GlobalToLocal(GlobalPosition));
				LocalPosition = m_TypingModule.GetInsertionPosition(LocalPosition);

				auto InsertionPosition = GetNearestCaretPosition(LocalPosition);
				ContentWithInsertion.insert(InsertionPosition, m_TypingModule.GetString());
			}
		}
	}

	glColor3d(0, 0, 0);
	OpenGLStream OpenGLStream(GetPosition());
	OpenGLStream << ContentWithInsertion.substr(0, std::min(m_CaretPosition, m_SelectionPosition));

	Vector2n CaretPosition;

	// Remember caret position at selection front
	if (std::min(m_CaretPosition, m_SelectionPosition) == m_CaretPosition)
	{
		CaretPosition = OpenGLStream.GetCaretPosition();
	}

	// Draw selected text as highlighted
	if (HasTypingFocus())
	{
		OpenGLStream.SetBackgroundColor(Color(static_cast<uint8>(195), 212, 242));
	}
	else
	{
		OpenGLStream.SetBackgroundColor(Color(static_cast<uint8>(212), 212, 212));
	}
	auto SelectionLength = std::max(m_CaretPosition, m_SelectionPosition) - std::min(m_CaretPosition, m_SelectionPosition);
	OpenGLStream << ContentWithInsertion.substr(std::min(m_CaretPosition, m_SelectionPosition), SelectionLength);
	OpenGLStream.SetBackgroundColor(Color(1.0, 1.0, 1.0));

	// Remember caret position at selection back
	if (std::max(m_CaretPosition, m_SelectionPosition) == m_CaretPosition)
	{
		CaretPosition = OpenGLStream.GetCaretPosition();
	}

	OpenGLStream << ContentWithInsertion.substr(std::max(m_CaretPosition, m_SelectionPosition));

	//if (CheckHover())
	// HACK
	if (HasTypingFocus())
	{
		// Draw caret
		//if (static_cast<int>(glfwGetTime() * 2) % 2)
		{
			glPushMatrix();
			glTranslated(CaretPosition.X(), CaretPosition.Y(), 0);
			glColor3d(0, 0, 0);
			glBegin(GL_QUADS);
				glVertex2d(-1, 0);
				glVertex2d(-1, lineHeight);
				glVertex2d(+1, lineHeight);
				glVertex2d(+1, 0);
			glEnd();
			glPopMatrix();
		}
	}
}
Ejemplo n.º 14
0
BOOL CDib::Draw(CDC* pDC,CRect rcDest,CPoint pntSrc)
/*-----------------------------------------------------------------------------
pDC:	Device context pointer to do output to.
rcDest:	Rectangle on DC to do output to.
pntSrc:	Coordinate of the lower-left corner of the DIB to output into rcDest.
-----------------------------------------------------------------------------*/
{
	/* Check for valid DIB handle */
	if ((m_lpBMIH == NULL) /*|| (m_hPalette == NULL)*/) return FALSE;

	BOOL     bSuccess=FALSE; //Success/fail flag
	HPALETTE hOldPal=NULL; //Previous palette (our DIB's palette is m_hPalette)
	CSize	 dibsize = GetDimensions(); //Get DIB's dimensions

	// Select as background since we have already realized in forground if needed
	hOldPal = ::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
	if (pDC->IsPrinting())   // printer DC
	{
		// get size of printer page (in pixels)
		int cxPage = pDC->GetDeviceCaps(HORZRES);
		int cyPage = pDC->GetDeviceCaps(VERTRES);
		// get printer pixels per inch
		int cxInch = pDC->GetDeviceCaps(LOGPIXELSX);
		int cyInch = pDC->GetDeviceCaps(LOGPIXELSY);

		// Best Fit case -- create a rectangle which preserves
		// the DIB's aspect ratio, and fills the page horizontally.
		//
		// The formula in the "->bottom" field below calculates the Y
		// position of the printed bitmap, based on the size of the
		// bitmap, the width of the page, and the relative size of
		// a printed pixel (cyInch / cxInch).
		rcDest.top = rcDest.left = 0;
		rcDest.bottom = (int)(((double)dibsize.cy*cxPage*cyInch)
				/((double)dibsize.cx*cxInch));
		rcDest.right = cxPage;
	}
	/* Make sure to use the stretching mode best for color pictures */
	::SetStretchBltMode(pDC->GetSafeHdc(), COLORONCOLOR);
	/* Determine whether to call StretchDIBits or SetDIBitsToDevice */
	if (dibsize == rcDest.Size()) {
		bSuccess = ::SetDIBitsToDevice(
			pDC->GetSafeHdc(),		//handle of device context
			rcDest.left,			//x-coordinate of upper-left corner of dest. rect.
			rcDest.top,				//y-coordinate of upper-left corner of dest. rect.
			rcDest.Width(),			//source rectangle width
			rcDest.Height(),		//source rectangle height
			pntSrc.x,				//x-coordinate of lower-left corner of source rect.
			pntSrc.y,				//y-coordinate of lower-left corner of source rect.
			0,						//first scan line in array
			rcDest.Height(),		//number of scan lines
			m_lpImage,				//address of array with DIB bits
			(LPBITMAPINFO)m_lpBMIH,	//address of structure with bitmap info.
			DIB_RGB_COLORS);		//RGB or palette indices
	}
	else {
		bSuccess = ::StretchDIBits(
			pDC->GetSafeHdc(),		//handle of device context
			rcDest.left,			//x-coordinate of upper-left corner of dest. rect.
			rcDest.top,				//y-coordinate of upper-left corner of dest. rect.
			rcDest.Width(),			//width of destination rectangle
			rcDest.Height(),		//height of destination rectangle
			pntSrc.x,				//x-coordinate of upper-left corner of source rect.
			pntSrc.y,				//y-coordinate of upper-left corner of source rect.
			m_lpBMIH->biWidth,		//width of source rectangle
			m_lpBMIH->biHeight,		//height of source rectangle
			m_lpImage,				//address of bitmap bits
			(LPBITMAPINFO)m_lpBMIH,	//address of bitmap data
			DIB_RGB_COLORS,			//usage
			SRCCOPY);				//raster operation code
	}
	/* Reselect old palette */
	if (hOldPal != NULL)
	{
		::SelectPalette(pDC->GetSafeHdc(), hOldPal, TRUE);
	}
    return bSuccess;
}