DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90, BufferLayout layout, bool use_rotator_downscale) { DisplayError error = kErrorNone; float scale_x = 1.0f; float scale_y = 1.0f; error = GetScaleFactor(crop, dst, &scale_x, &scale_y); if (error != kErrorNone) { return error; } error = ValidateDownScaling(scale_x, scale_y, (layout != kLinear)); if (error != kErrorNone) { return error; } error = ValidateUpScaling(scale_x, scale_y); if (error != kErrorNone) { return error; } return kErrorNone; }
void Core::StartDrawing(int mode) { lowPushMatrix(); // Calcul du scaling par rapport à l'horizontale ConfigureViewport(); //Parametrage selon le mode d'affichage if(mode == MODE_2D) { lowSetProjectionOrtho(mWindowWidth, mBaseHeight*GetScaleFactor()); // Translation (bandes noires) // TODO : finir gestion des écrans 4/3, 16/10 //lowTranslate(0, -(mWindowHeight - mBaseHeight)*scaleFactor/2.0f); lowScale(GetScaleFactor(), GetScaleFactor()); glDepthMask(GL_TRUE); } else if(mode == MODE_2D_BACKGROUND) { lowSetProjectionOrtho(mWindowWidth, mBaseHeight*GetScaleFactor()); lowScale(GetScaleFactor(), GetScaleFactor()); glDepthMask(GL_TRUE); } else { lowSetProjectionPerspective(mWindowWidth, mBaseHeight*GetScaleFactor()); glDepthMask(GL_TRUE); } }
void CFreetypeFontFace::ApplyFTSize() { const float fScale = GetScaleFactor(); FT_Error err = 0; if (m_nDpi == -1) { err = FT_Set_Pixel_Sizes(m_pFont->GetFontFace(), (int32_t)(m_nSize * fScale), (int32_t)(m_nSize * fScale)); BEATS_ASSERT(!err); } else { FT_F26Dot6 sizeTrans = (int32_t)(m_nSize * fScale) << FT_SHIFT_NUM; err = FT_Set_Char_Size(m_pFont->GetFontFace(), sizeTrans, sizeTrans, m_nDpi, m_nDpi); BEATS_ASSERT(!err); } const FT_Size& ftSize = m_pFont->GetFontFace()->size; m_nAscender = ftSize->metrics.ascender >> FT_SHIFT_NUM; int32_t descender = ftSize->metrics.descender >> FT_SHIFT_NUM; m_nLineHeight = MAX(m_nLineHeight, m_nAscender - descender); }
void SVirtualJoystick::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) { SLeafWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); if (State == State_WaitForStart || State == State_CountingDownToStart) { CurrentOpacity = 0.f; } else { // lerp to the desired opacity based on whether the user is interacting with the joystick CurrentOpacity = FMath::Lerp(CurrentOpacity, GetBaseOpacity(), OPACITY_LERP_RATE * InDeltaTime); } // count how many controls are active int32 NumActiveControls = 0; for (int32 ControlIndex = 0; ControlIndex < Controls.Num(); ControlIndex++) { FControlInfo& Control = Controls[ControlIndex]; if (Control.bNeedUpdatedCenter) { Control.ElapsedTime += InDeltaTime; if (Control.ElapsedTime > ActivationDelay) { Control.bNeedUpdatedCenter = false; CurrentOpacity = ActiveOpacity; if (!bPreventReCenter) { Control.VisualCenter = Control.NextCenter; } HandleTouch(ControlIndex, Control.NextCenter, AllottedGeometry.Size); } } // calculate absolute positions based on geometry // @todo: Need to manage geometry changing! if (!Control.bHasBeenPositioned) { // figure out how much to scale the control sizes float ScaleFactor = GetScaleFactor(AllottedGeometry); // update all the sizes Control.Center = FVector2D(ResolveRelativePosition(Control.Center.X, AllottedGeometry.Size.X, ScaleFactor), ResolveRelativePosition(Control.Center.Y, AllottedGeometry.Size.Y, ScaleFactor)); Control.VisualCenter = Control.Center; Control.VisualSize = FVector2D(ResolveRelativePosition(Control.VisualSize.X, AllottedGeometry.Size.X, ScaleFactor), ResolveRelativePosition(Control.VisualSize.Y, AllottedGeometry.Size.Y, ScaleFactor)); Control.InteractionSize = FVector2D(ResolveRelativePosition(Control.InteractionSize.X, AllottedGeometry.Size.X, ScaleFactor), ResolveRelativePosition(Control.InteractionSize.Y, AllottedGeometry.Size.Y, ScaleFactor)); Control.ThumbSize = FVector2D(ResolveRelativePosition(Control.ThumbSize.X, AllottedGeometry.Size.X, ScaleFactor), ResolveRelativePosition(Control.ThumbSize.Y, AllottedGeometry.Size.Y, ScaleFactor)); // Control.InputScale = Control.InputScale * ScaleFactor; Control.bHasBeenPositioned = true; } if (Control.CapturedPointerIndex >= 0 || Control.bSendOneMoreEvent) { Control.bSendOneMoreEvent = false; // now pass the fake joystick events to the game // Assume that joystick size is all equal float JoysticInputSize = Control.ThumbPosition.Size() * 2.f / Control.VisualSize.X; FVector2D NormalizedOffset = Control.ThumbPosition.SafeNormal() * Control.InputScale * JoysticInputSize; EControllerButtons::Type XAxis = ControlIndex == 0 ? EControllerButtons::LeftAnalogX : EControllerButtons::RightAnalogX; EControllerButtons::Type YAxis = ControlIndex == 0 ? EControllerButtons::LeftAnalogY : EControllerButtons::RightAnalogY; // UE_LOG(LogTemp, Log, TEXT("Joysticking %f,%f"), NormalizedOffset.X, -NormalizedOffset.Y); FSlateApplication::Get().SetJoystickCaptorToGameViewport(); FSlateApplication::Get().OnControllerAnalog(Control.MainInputKey, 0, NormalizedOffset.X); FSlateApplication::Get().OnControllerAnalog(Control.AltInputKey, 0, -NormalizedOffset.Y); } // is this active? if (Control.CapturedPointerIndex != -1) { NumActiveControls++; } } // STATE MACHINE! if (NumActiveControls > 0 || bPreventReCenter) { // any active control snaps the state to active immediately State = State_Active; } else { switch (State) { case State_WaitForStart: { State = State_CountingDownToStart; Countdown = StartupDelay; } break; case State_CountingDownToStart: // update the countdown Countdown -= InDeltaTime; if (Countdown <= 0.0f) { State = State_Inactive; } break; case State_Active: if (NumActiveControls == 0) { // start going to inactive State = State_CountingDownToInactive; Countdown = TimeUntilDeactive; } break; case State_CountingDownToInactive: // update the countdown Countdown -= InDeltaTime; if (Countdown <= 0.0f) { // should we start counting down to a control reset? if (TimeUntilReset > 0.0f) { State = State_CountingDownToReset; Countdown = TimeUntilReset; } else { // if not, then just go inactive State = State_Inactive; } } break; case State_CountingDownToReset: Countdown -= InDeltaTime; if (Countdown <= 0.0f) { // reset all the controls for (int32 ControlIndex = 0; ControlIndex < Controls.Num(); ControlIndex++) { Controls[ControlIndex].Reset(); } // finally, go inactive State = State_Inactive; } break; } } }
void Core::ConfigureViewport() { float h = (mWindowHeight - mBaseHeight*GetScaleFactor()) / 2.0f; lowViewport(0, h, Core::getWindowWidth(), Core::getBaseHeight()*Core::GetScaleFactor() ); }
//--------------------------------------------------------------------------- int TMissionEditor::DivScaleFactor(int p) { //converts pixel value from world cm value return int(p/GetScaleFactor()); }
//--------------------------------------------------------------------------- int TMissionEditor::MulScaleFactor(int w) { //converts world cm value from pixels value return int(w*GetScaleFactor()); }
const CFontGlyph *CFreetypeFontFace::PrepareChar(wchar_t character, bool& bGlyphRestFlag) { bGlyphRestFlag = false; m_glyphMapLocker.lock(); auto itr = m_glyphMap.find(character); CFreetypeFontGlyph *pGlyph = itr != m_glyphMap.end() ? down_cast<CFreetypeFontGlyph *>(itr->second) : nullptr; m_glyphMapLocker.unlock(); if (!pGlyph) { float outlineWidth = GetBorderWeight() * GetScaleFactor(); ApplyFTSize(); FT_Face pFontFace = m_pFont->GetFontFace(); BEATS_ASSERT(pFontFace != NULL); bool bFindCharacterGlyph = FT_Get_Char_Index(pFontFace, character) != 0; BEYONDENGINE_UNUSED_PARAM(bFindCharacterGlyph); BEATS_ASSERT(bFindCharacterGlyph, _T("Character %d can't be found in all font face!"), character); FT_Error err = FT_Load_Char(pFontFace, character, FT_LOAD_NO_BITMAP); BEYONDENGINE_UNUSED_PARAM(err); BEATS_ASSERT(!err); FT_GlyphSlot pGlyphSlot = pFontFace->glyph; BEATS_ASSERT(pGlyphSlot != NULL); int32_t nBorderAdvanceX = pGlyphSlot->metrics.horiAdvance >> FT_SHIFT_NUM; int32_t nBorderAdvanceY = m_nLineHeight + (uint32_t)ceil(outlineWidth * 2.0f); int32_t nFontAdvanceX = nBorderAdvanceX; int32_t nFontHeight = 0; int32_t nBorderOriginWidth = 0; int32_t nFontOriginWidth = 0; int32_t nBorderHeight = 0; FT_BBox borderBox; FT_BBox fontBox; int32_t x = 0, y = 0; if (pGlyphSlot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Library ftLib = CFont::GetLibrary(); // Set up a stroker. FT_Stroker stroker; FT_Stroker_New(ftLib, &stroker); FT_Stroker_Set(stroker, (int32_t)(outlineWidth * 64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); FT_Glyph pOutlineGlyph, pInnerGlyph; if (FT_Get_Glyph(pGlyphSlot, &pOutlineGlyph) == 0 && FT_Get_Glyph(pGlyphSlot, &pInnerGlyph) == 0) { FT_Glyph_StrokeBorder(&pOutlineGlyph, stroker, 0, 1); BEATS_ASSERT(pOutlineGlyph->format == FT_GLYPH_FORMAT_OUTLINE && pInnerGlyph->format == FT_GLYPH_FORMAT_OUTLINE); FT_Outline *pOutLine = &reinterpret_cast<FT_OutlineGlyph>(pOutlineGlyph)->outline; FT_Glyph_Get_CBox(pOutlineGlyph, FT_GLYPH_BBOX_GRIDFIT, &borderBox); FT_Glyph_Get_CBox(pInnerGlyph, FT_GLYPH_BBOX_GRIDFIT, &fontBox); nBorderOriginWidth = (borderBox.xMax - borderBox.xMin) >> FT_SHIFT_NUM; nFontOriginWidth = (fontBox.xMax - fontBox.xMin) >> FT_SHIFT_NUM; int32_t nBorderWidth = nextMOE(nBorderOriginWidth); // Because our GL_UNPACK_ALIGNMENT should be 8 here. nBorderHeight = (borderBox.yMax - borderBox.yMin) >> FT_SHIFT_NUM; nFontHeight = (fontBox.yMax - fontBox.yMin) >> FT_SHIFT_NUM; x = pGlyphSlot->metrics.horiBearingX >> FT_SHIFT_NUM; y = pGlyphSlot->metrics.horiBearingY >> FT_SHIFT_NUM; if(nBorderAdvanceX < x + nBorderOriginWidth) // It is true for most of the time, because border size always greater than nAdvanceX { nBorderAdvanceX = x + nBorderOriginWidth; } if (nFontAdvanceX < x + nFontOriginWidth) { nFontAdvanceX = nFontOriginWidth; } if(m_uCurrX + x + nBorderWidth > PAGE_WIDTH) { m_uCurrX = 0; m_uCurrY += (nBorderAdvanceY + m_nBorderSpace); if (m_uCurrY + nBorderAdvanceY > PAGE_HEIGHT) { BEATS_WARNING(false, "Freetype texture buffer overflow for %d glyphs, we will rebuild this texture buffer.", (uint32_t)m_glyphMap.size()); ResetGlyphs(); bGlyphRestFlag = true; return nullptr; } } int32_t nDataSize = nBorderWidth * nBorderHeight; float fBorderOffsetY = 1.0f; // Makes it look like a shadow. unsigned char* pBorderData = RenderFontDataToBmp(nBorderWidth, nBorderHeight, -borderBox.xMin, (int32_t)(-borderBox.yMin * fBorderOffsetY), pOutLine); FT_Outline *pInnerOutLine = &reinterpret_cast<FT_OutlineGlyph>(pInnerGlyph)->outline; unsigned char* pFontData = RenderFontDataToBmp(nBorderWidth, nBorderHeight, -borderBox.xMin, -borderBox.yMin, pInnerOutLine); unsigned char* pAllData = new unsigned char[nDataSize * 2]; for (int32_t i = 0; i < nDataSize; ++i) { pAllData[i * 2] = pBorderData[i]; pAllData[i * 2 + 1] = pFontData[i]; } BEATS_ASSERT(m_pTexture.Get() != nullptr); GLint nX = MAX((int32_t)m_uCurrX + x, 0); GLint nY = MAX((int32_t)m_uCurrY + (m_nAscender - y), 0); SFontUpdateImageInfo* pImageInfo = new SFontUpdateImageInfo; pImageInfo->m_pTexture = m_pTexture; pImageInfo->m_nWidth = nBorderWidth; pImageInfo->m_nHeight = nBorderHeight; pImageInfo->m_x = nX; pImageInfo->m_y = nY; pImageInfo->m_pData = pAllData; m_fontUpdateImageCacheMutex.lock(); m_fontUpdateImageCache.push_back(pImageInfo); m_fontUpdateImageCacheMutex.unlock(); // Clean up afterwards. FT_Stroker_Done(stroker); FT_Done_Glyph(pOutlineGlyph); FT_Done_Glyph(pInnerGlyph); BEATS_SAFE_DELETE_ARRAY(pBorderData); BEATS_SAFE_DELETE_ARRAY(pFontData); }