Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
HARP-6487: Do not use default text placements anymore.
Browse files Browse the repository at this point in the history
This commit finally switches the alternative text placement
algorithm to use only theme defined list of possible placements.
Default/hard-coded placement alternatives are no longer used.

Signed-off-by: Krystian Kostecki <ext-krystian.kostecki@here.com>
  • Loading branch information
kkostecki committed May 14, 2020
1 parent 8b7ab79 commit c25451b
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 61 deletions.
51 changes: 6 additions & 45 deletions @here/harp-mapview/lib/text/Placement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ import { Env, getPropertyValue, PoiTechnique } from "@here/harp-datasource-proto
import { OrientedBox3, Projection, ProjectionType } from "@here/harp-geoutils";
import {
hAlignFromPlacement,
HorizontalAlignment,
HorizontalPlacement,
hPlacementFromAlignment,
MeasurementParameters,
TextCanvas,
TextPlacement,
vAlignFromPlacement,
VerticalAlignment,
VerticalPlacement,
vPlacementFromAlignment
} from "@here/harp-text-canvas";
Expand Down Expand Up @@ -128,32 +126,6 @@ export enum PrePlacementResult {
Count
}

/**
* @hidden
* Possible placement scenarios in clock-wise order, based on centered placements.
*
* TODO: HARP-6487 This array should be parsed from the theme style definition.
*/
const anchorPlacementsCentered: TextPlacement[] = [
{ h: HorizontalPlacement.Center, v: VerticalPlacement.Top },
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Center },
{ h: HorizontalPlacement.Center, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Center }
];

/**
* @hidden
* Placement anchors in clock-wise order, for corner based placements.
*
* TODO: HARP-6487 This array should be parsed from the theme style definition.
*/
const anchorPlacementsCornered: TextPlacement[] = [
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Top },
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Top }
];

const tmpPlacementPosition = new THREE.Vector3();
const tmpPlacementBounds = new THREE.Box2();

Expand Down Expand Up @@ -403,14 +375,11 @@ export function placePointLabel(
if (isRejected && newLabel) {
return PlacementResult.Invisible;
}
// For centered point labels and labels with icon rejected, do only current anchor testing.
// TODO: HARP-6487 Placements options should be provided from theme style definition.
if (
!multiAnchor ||
isRejected ||
(layoutStyle.verticalAlignment === VerticalAlignment.Center &&
layoutStyle.horizontalAlignment === HorizontalAlignment.Center)
) {
// Check if alternative placements have been provided.
multiAnchor =
multiAnchor && layoutStyle.placements !== undefined && layoutStyle.placements.length > 1;
// For single placement labels or labels with icon rejected, do only current anchor testing.
if (!multiAnchor || isRejected) {
return placePointLabelAtCurrentAnchor(
labelState,
screenPosition,
Expand Down Expand Up @@ -472,18 +441,10 @@ function placePointLabelChoosingAnchor(
// Store label state - persistent or new label.
const persistent = labelState.visible;

// The current implementation does not provide placements options via theme style yet,
// so function tries the anchor placements from pre-defined placements arrays.
// TODO: HARP-6487 Placements options should be loaded from the theme.

// Start with last alignment settings if layout state was stored or
// simply begin from layout defined in theme.
const lastPlacement = labelState.textPlacement;
const placementCentered =
lastPlacement.h === HorizontalPlacement.Center ||
lastPlacement.v === VerticalPlacement.Center;
// TODO: HARP-6487: Read placements options from label.layoutStyle.placements.
const placements = placementCentered ? anchorPlacementsCentered : anchorPlacementsCornered;
const placements = label.layoutStyle!.placements;
const placementsNum = placements.length;
// Find current anchor placement on the optional placements list.
// Index of exact match.
Expand Down
133 changes: 117 additions & 16 deletions @here/harp-mapview/test/PlacementTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
TextLayoutParameters,
TextLayoutStyle,
TextPlacement,
TextPlacements,
TextRenderParameters,
TextRenderStyle,
VerticalAlignment,
Expand All @@ -56,6 +57,26 @@ const screenBottomLeft = new THREE.Vector2(-screenWidth / 2, screenHeight / 2);
const screenBottomCenter = new THREE.Vector2(0, screenHeight / 2);
const screenBottomRight = new THREE.Vector2(screenWidth / 2, screenHeight / 2);

/**
* Possible placement scenarios in clock-wise order, based on centered placements.
*/
const placementsCentered: TextPlacement[] = [
{ h: HorizontalPlacement.Center, v: VerticalPlacement.Top },
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Center },
{ h: HorizontalPlacement.Center, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Center }
];

/**
* Placement anchors in clock-wise order, for corner based placements.
*/
const placementsCornered: TextPlacement[] = [
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Top },
{ h: HorizontalPlacement.Right, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Bottom },
{ h: HorizontalPlacement.Left, v: VerticalPlacement.Top }
];

async function createTextElement(
textCanvas: TextCanvas,
text: string,
Expand Down Expand Up @@ -129,6 +150,26 @@ function createTextElementsStates(textElements: TextElement[]): TextElementState
return textElements.map(element => createTextElementState(element));
}

function createTextPlacements(
baseHPlacement: HorizontalPlacement,
baseVPlacement: VerticalPlacement
): TextPlacements {
const placementCentered =
baseHPlacement === HorizontalPlacement.Center ||
baseVPlacement === VerticalPlacement.Center;
const placements = placementCentered ? placementsCentered : placementsCornered;
const placementsNum = placements.length;
// Find first placement on the placements list.
const firstIdx = placements.findIndex(p => p.h === baseHPlacement && p.v === baseVPlacement);
expect(firstIdx >= 0).to.be.true;
const result: TextPlacements = [];
// Iterate all placements starting from the first one and create full clock wise placement list.
for (let i = firstIdx; i < placementsNum + firstIdx; ++i) {
result.push(placements[i % placementsNum]);
}
return result;
}

describe("Placement", function() {
const sandbox = sinon.createSandbox();
let textCanvas: TextCanvas;
Expand Down Expand Up @@ -480,7 +521,11 @@ describe("Placement", function() {
position: new THREE.Vector2(-10, -10).add(screenTopLeft),
layout: {
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Below
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Bottom
)
},
placement: {
h: HorizontalPlacement.Right,
Expand All @@ -493,7 +538,11 @@ describe("Placement", function() {
position: new THREE.Vector2(10, -10).add(screenTopRight),
layout: {
horizontalAlignment: HorizontalAlignment.Left,
verticalAlignment: VerticalAlignment.Below
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Right,
VerticalPlacement.Bottom
)
},
placement: {
h: HorizontalPlacement.Left,
Expand All @@ -506,7 +555,11 @@ describe("Placement", function() {
position: new THREE.Vector2(10, 10).add(screenBottomRight),
layout: {
horizontalAlignment: HorizontalAlignment.Left,
verticalAlignment: VerticalAlignment.Above
verticalAlignment: VerticalAlignment.Above,
placements: createTextPlacements(
HorizontalPlacement.Right,
VerticalPlacement.Top
)
},
placement: {
h: HorizontalPlacement.Left,
Expand All @@ -519,7 +572,11 @@ describe("Placement", function() {
position: new THREE.Vector2(-10, 10).add(screenBottomLeft),
layout: {
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Above
verticalAlignment: VerticalAlignment.Above,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Top
)
},
placement: {
h: HorizontalPlacement.Right,
Expand All @@ -532,7 +589,11 @@ describe("Placement", function() {
position: new THREE.Vector2(-10, 0).add(screenCenterLeft),
layout: {
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Center
verticalAlignment: VerticalAlignment.Center,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Center
)
},
// Layout changed horizontally and vertically (clock-wise) to move
// text away from screen edge.
Expand All @@ -547,7 +608,11 @@ describe("Placement", function() {
position: new THREE.Vector2(10, 0).add(screenCenterRight),
layout: {
horizontalAlignment: HorizontalAlignment.Left,
verticalAlignment: VerticalAlignment.Center
verticalAlignment: VerticalAlignment.Center,
placements: createTextPlacements(
HorizontalPlacement.Right,
VerticalPlacement.Center
)
},
// Layout changed horizontally and vertically (clock-wise).
placement: {
Expand All @@ -561,7 +626,11 @@ describe("Placement", function() {
position: new THREE.Vector2(0, -10).add(screenTopCenter),
layout: {
horizontalAlignment: HorizontalAlignment.Center,
verticalAlignment: VerticalAlignment.Below
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Center,
VerticalPlacement.Bottom
)
},
placement: {
h: HorizontalPlacement.Left,
Expand All @@ -574,7 +643,11 @@ describe("Placement", function() {
position: new THREE.Vector2(0, 10).add(screenBottomCenter),
layout: {
horizontalAlignment: HorizontalAlignment.Center,
verticalAlignment: VerticalAlignment.Above
verticalAlignment: VerticalAlignment.Above,
placements: createTextPlacements(
HorizontalPlacement.Center,
VerticalPlacement.Top
)
},
placement: {
h: HorizontalPlacement.Right,
Expand Down Expand Up @@ -675,7 +748,11 @@ describe("Placement", function() {
position: new THREE.Vector2(-10, 0).add(screenCenterLeft),
layout: {
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Center
verticalAlignment: VerticalAlignment.Center,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Center
)
},
fading: false,
frames: [
Expand Down Expand Up @@ -705,7 +782,11 @@ describe("Placement", function() {
position: new THREE.Vector2(10, 0).add(screenCenterRight),
layout: {
horizontalAlignment: HorizontalAlignment.Left,
verticalAlignment: VerticalAlignment.Center
verticalAlignment: VerticalAlignment.Center,
placements: createTextPlacements(
HorizontalPlacement.Right,
VerticalPlacement.Center
)
},
fading: false,
frames: [
Expand All @@ -731,7 +812,11 @@ describe("Placement", function() {
position: new THREE.Vector2(0, -10).add(screenTopCenter),
layout: {
horizontalAlignment: HorizontalAlignment.Center,
verticalAlignment: VerticalAlignment.Below
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Center,
VerticalPlacement.Bottom
)
},
fading: false,
frames: [
Expand All @@ -757,7 +842,11 @@ describe("Placement", function() {
position: new THREE.Vector2(0, 10).add(screenBottomCenter),
layout: {
horizontalAlignment: HorizontalAlignment.Center,
verticalAlignment: VerticalAlignment.Above
verticalAlignment: VerticalAlignment.Above,
placements: createTextPlacements(
HorizontalPlacement.Center,
VerticalPlacement.Top
)
},
fading: false,
frames: [
Expand Down Expand Up @@ -877,6 +966,10 @@ describe("Placement", function() {
{
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Bottom
),
wrappingMode: WrappingMode.None
}
);
Expand Down Expand Up @@ -953,6 +1046,12 @@ describe("Placement", function() {
{
horizontalAlignment: HorizontalAlignment.Center,
verticalAlignment: VerticalAlignment.Center,
placements: [
{
h: HorizontalPlacement.Center,
v: VerticalPlacement.Center
}
],
wrappingMode: WrappingMode.None
}
);
Expand All @@ -979,10 +1078,8 @@ describe("Placement", function() {
outPositions[i],
true
);
// Even with multi-placement turned on, the labels are not using
// alternative placement algorithm - they are excluded.
// TODO: HARP-6487 This may be due to change when placements will be
// parsed from theme.
// Even with multi-placement turned on, only single placement has been provided
// alternative placement algorithm will have no options, but surrender.
expect(states[i].textPlacement.h).to.equal(HorizontalPlacement.Center);
expect(states[i].textPlacement.v).to.equal(VerticalPlacement.Center);
}
Expand All @@ -1001,6 +1098,10 @@ describe("Placement", function() {
{
horizontalAlignment: HorizontalAlignment.Right,
verticalAlignment: VerticalAlignment.Below,
placements: createTextPlacements(
HorizontalPlacement.Left,
VerticalPlacement.Bottom
),
wrappingMode: WrappingMode.None
}
);
Expand Down

0 comments on commit c25451b

Please sign in to comment.